cgma
|
00001 #include <assert.h> 00002 00003 #include "CompositeEngine.hpp" 00004 #include "PartitionEngine.hpp" 00005 00006 #include "DLIList.hpp" 00007 #include "TDUniqueId.hpp" 00008 #include "CubitTransformMatrix.hpp" 00009 #include "RTree.hpp" 00010 00011 #include "CompositePoint.hpp" 00012 #include "CompositeCurve.hpp" 00013 #include "CompositeCoEdge.hpp" 00014 #include "CompositeLoop.hpp" 00015 #include "CompositeSurface.hpp" 00016 #include "CompositeShell.hpp" 00017 #include "CompositeLump.hpp" 00018 #include "CompositeBody.hpp" 00019 #include "GfxPreview.hpp" 00020 00021 #include "PartitionPoint.hpp" 00022 #include "SegmentedCurve.hpp" 00023 00024 #include "CADefines.hpp" 00025 00026 #include "VGLoopTool.hpp" 00027 #include "Body.hpp" 00028 #include "LumpSM.hpp" 00029 00030 #include "GeometryQueryTool.hpp" 00031 #include "AppUtil.hpp" 00032 #include "GeometryEvent.hpp" 00033 00034 typedef VGLoopTool<CompositeSurface, 00035 CompositeLoop, 00036 CompositeCoEdge, 00037 CompositeCurve, 00038 CompositePoint> CompLoopTool; 00039 00040 CompositeEngine* CompositeEngine::instance_ = NULL; 00041 00042 00043 CompositeEngine::~CompositeEngine() 00044 { 00045 GeometryQueryTool::instance()->unregister_intermediate_engine(this); 00046 } 00047 00048 void CompositeEngine::delete_instance() 00049 { 00050 if( NULL != instance_ ) 00051 { 00052 delete instance_; 00053 instance_ = NULL; 00054 } 00055 } 00056 00057 CompositeEngine& CompositeEngine::instance() 00058 { 00059 if( instance_ == NULL ) 00060 { 00061 instance_ = new CompositeEngine(); 00062 assert( instance_ != NULL ); 00063 } 00064 00065 return *instance_; 00066 } 00067 00068 // This function goes through all of the curves and vertices and 00069 // removes any named attributes specified below. 00070 void CompositeEngine::remove_imprint_attributes_after_modify( DLIList<BodySM*> &old_sms, 00071 DLIList<BodySM*> &new_sms ) 00072 { 00073 int k, m, q, w, g, b, s, t; 00074 CubitString name("IMPRINT_PREEXISTING"); 00075 std::vector<CubitString> string_list; 00076 string_list.push_back( name ); 00077 CubitSimpleAttrib geom_attrib( &string_list, 0, 0 ); 00078 00079 DLIList<BodySM*> all_sms = old_sms; 00080 all_sms += new_sms; 00081 DLIList<TopologyBridge*> top_bridges; 00082 CAST_LIST_TO_PARENT(all_sms, top_bridges); 00083 for(k=top_bridges.size(); k--;) 00084 { 00085 TopologyBridge *cur_body = top_bridges.get_and_step(); 00086 DLIList<TopologyBridge*> lumps; 00087 cur_body->get_children_virt(lumps); 00088 for(m=lumps.size(); m--;) 00089 { 00090 TopologyBridge *cur_lump = lumps.get_and_step(); 00091 DLIList<TopologyBridge*> shells; 00092 cur_lump->get_children_virt(shells); 00093 for(q=shells.size(); q--;) 00094 { 00095 TopologyBridge *cur_shell = shells.get_and_step(); 00096 DLIList<TopologyBridge*> surfaces; 00097 cur_shell->get_children_virt(surfaces); 00098 for(w=surfaces.size(); w--;) 00099 { 00100 TopologyBridge *cur_surface = surfaces.get_and_step(); 00101 DLIList<TopologyBridge*> loops; 00102 cur_surface->get_children_virt(loops); 00103 for(g=loops.size(); g--;) 00104 { 00105 TopologyBridge *cur_loop = loops.get_and_step(); 00106 DLIList<TopologyBridge*> coedges; 00107 cur_loop->get_children_virt(coedges); 00108 for(b=coedges.size(); b--;) 00109 { 00110 TopologyBridge *cur_coedge = coedges.get_and_step(); 00111 DLIList<TopologyBridge*> curves; 00112 cur_coedge->get_children_virt(curves); 00113 for(s=curves.size(); s--;) 00114 { 00115 TopologyBridge *cur_curve = curves.get_and_step(); 00116 DLIList<CubitSimpleAttrib> list; 00117 cur_curve->get_simple_attribute("IMPRINT_PREEXISTING",list); 00118 if(list.size() != 0) 00119 cur_curve->remove_simple_attribute_virt(list.get()); 00120 DLIList<TopologyBridge*> pts; 00121 cur_curve->get_children_virt(pts); 00122 for(t=pts.size(); t--;) 00123 { 00124 TopologyBridge *cur_pt = pts.get_and_step(); 00125 list.clean_out(); 00126 cur_pt->get_simple_attribute("IMPRINT_PREEXISTING",list); 00127 if(list.size() != 0) 00128 cur_pt->remove_simple_attribute_virt(list.get()); 00129 } 00130 } 00131 } 00132 } 00133 } 00134 } 00135 } 00136 } 00137 } 00138 00139 void CompositeEngine::push_imprint_attributes_before_modify 00140 ( DLIList<BodySM*> &bodies) 00141 { 00142 } 00143 00144 void CompositeEngine::push_named_attributes_to_curves_and_points 00145 // ( DLIList<BodySM*> &bodies, char *name_in) 00146 ( DLIList<TopologyBridge*> &in_list, const char *name_in) 00147 { 00148 int i/*, k, m, q, w, g, b, s, t*/; 00149 CubitString name(name_in); 00150 std::vector<CubitString> string_list; 00151 string_list.push_back( name ); 00152 CubitSimpleAttrib attrib( &string_list, 0, 0 ); 00153 00154 for(i=in_list.size(); i>0; i--) 00155 { 00156 TopologyBridge *tb = in_list.get_and_step(); 00157 if(dynamic_cast<BodySM*>(tb)) 00158 { 00159 DLIList<TopologyBridge*> lumps; 00160 tb->get_children_virt(lumps); 00161 push_named_attributes_to_curves_and_points(lumps, name_in); 00162 } 00163 else if(dynamic_cast<Lump*>(tb)) 00164 { 00165 DLIList<TopologyBridge*> shells; 00166 tb->get_children_virt(shells); 00167 push_named_attributes_to_curves_and_points(shells, name_in); 00168 } 00169 else if(dynamic_cast<ShellSM*>(tb)) 00170 { 00171 DLIList<TopologyBridge*> surfs; 00172 tb->get_children_virt(surfs); 00173 push_named_attributes_to_curves_and_points(surfs, name_in); 00174 } 00175 else if(dynamic_cast<Surface*>(tb)) 00176 { 00177 DLIList<TopologyBridge*> loops; 00178 tb->get_children_virt(loops); 00179 push_named_attributes_to_curves_and_points(loops, name_in); 00180 } 00181 else if(dynamic_cast<LoopSM*>(tb)) 00182 { 00183 DLIList<TopologyBridge*> coedges; 00184 tb->get_children_virt(coedges); 00185 push_named_attributes_to_curves_and_points(coedges, name_in); 00186 } 00187 else if(dynamic_cast<CoEdgeSM*>(tb)) 00188 { 00189 DLIList<TopologyBridge*> curves; 00190 tb->get_children_virt(curves); 00191 push_named_attributes_to_curves_and_points(curves, name_in); 00192 } 00193 else if(dynamic_cast<Curve*>(tb)) 00194 { 00195 append_attrib( tb, attrib ); 00196 DLIList<TopologyBridge*> points; 00197 tb->get_children_virt(points); 00198 push_named_attributes_to_curves_and_points(points, name_in); 00199 } 00200 else if(dynamic_cast<TBPoint*>(tb)) 00201 { 00202 append_attrib( tb, attrib ); 00203 } 00204 } 00205 00206 /* 00207 00208 00209 DLIList<TopologyBridge*> top_bridges; 00210 CAST_LIST_TO_PARENT(bodies, top_bridges); 00211 for(k=top_bridges.size(); k--;) 00212 { 00213 TopologyBridge *cur_body = top_bridges.get_and_step(); 00214 DLIList<TopologyBridge*> lumps; 00215 cur_body->get_children_virt(lumps); 00216 for(m=lumps.size(); m--;) 00217 { 00218 TopologyBridge *cur_lump = lumps.get_and_step(); 00219 DLIList<TopologyBridge*> shells; 00220 cur_lump->get_children_virt(shells); 00221 for(q=shells.size(); q--;) 00222 { 00223 TopologyBridge *cur_shell = shells.get_and_step(); 00224 DLIList<TopologyBridge*> surfaces; 00225 cur_shell->get_children_virt(surfaces); 00226 for(w=surfaces.size(); w--;) 00227 { 00228 TopologyBridge *cur_surface = surfaces.get_and_step(); 00229 DLIList<TopologyBridge*> loops; 00230 cur_surface->get_children_virt(loops); 00231 for(g=loops.size(); g--;) 00232 { 00233 TopologyBridge *cur_loop = loops.get_and_step(); 00234 DLIList<TopologyBridge*> coedges; 00235 cur_loop->get_children_virt(coedges); 00236 for(b=coedges.size(); b--;) 00237 { 00238 TopologyBridge *cur_coedge = coedges.get_and_step(); 00239 DLIList<TopologyBridge*> curves; 00240 cur_coedge->get_children_virt(curves); 00241 for(s=curves.size(); s--;) 00242 { 00243 TopologyBridge *cur_curve = curves.get_and_step(); 00244 append_attrib( cur_curve, &attrib ); 00245 DLIList<TopologyBridge*> pts; 00246 cur_curve->get_children_virt(pts); 00247 for(t=pts.size(); t--;) 00248 { 00249 TopologyBridge *cur_pt = pts.get_and_step(); 00250 append_attrib( cur_pt, &attrib ); 00251 } 00252 } 00253 } 00254 } 00255 } 00256 } 00257 } 00258 } 00259 */ 00260 } 00261 00262 void CompositeEngine::get_all_curves_and_points(DLIList<TopologyBridge*> &tb_list, 00263 DLIList<Curve*> &curves, 00264 DLIList<TBPoint*> &points) 00265 { 00266 int i; 00267 Curve *crv; 00268 TBPoint *pt; 00269 for(i=tb_list.size(); i>0; i--) 00270 { 00271 TopologyBridge *tb = tb_list.get_and_step(); 00272 if(dynamic_cast<BodySM*>(tb)) 00273 { 00274 DLIList<TopologyBridge*> lumps; 00275 tb->get_children_virt(lumps); 00276 get_all_curves_and_points(lumps, curves, points); 00277 } 00278 else if(dynamic_cast<Lump*>(tb)) 00279 { 00280 DLIList<TopologyBridge*> shells; 00281 tb->get_children_virt(shells); 00282 get_all_curves_and_points(shells, curves, points); 00283 } 00284 else if(dynamic_cast<ShellSM*>(tb)) 00285 { 00286 DLIList<TopologyBridge*> surfs; 00287 tb->get_children_virt(surfs); 00288 get_all_curves_and_points(surfs, curves, points); 00289 } 00290 else if(dynamic_cast<Surface*>(tb)) 00291 { 00292 DLIList<TopologyBridge*> loops; 00293 tb->get_children_virt(loops); 00294 get_all_curves_and_points(loops, curves, points); 00295 } 00296 else if(dynamic_cast<LoopSM*>(tb)) 00297 { 00298 DLIList<TopologyBridge*> coedges; 00299 tb->get_children_virt(coedges); 00300 get_all_curves_and_points(coedges, curves, points); 00301 } 00302 else if(dynamic_cast<CoEdgeSM*>(tb)) 00303 { 00304 DLIList<TopologyBridge*> tmp_curves; 00305 tb->get_children_virt(tmp_curves); 00306 get_all_curves_and_points(tmp_curves, curves, points); 00307 } 00308 else if((crv = dynamic_cast<Curve*>(tb))) 00309 { 00310 curves.append(crv); 00311 DLIList<TopologyBridge*> tmp_points; 00312 tb->get_children_virt(tmp_points); 00313 get_all_curves_and_points(tmp_points, curves, points); 00314 } 00315 else if((pt = dynamic_cast<TBPoint*>(tb))) 00316 { 00317 points.append(pt); 00318 } 00319 } 00320 } 00321 00322 // Function to apply/remove COMPOSITE_GEOM attributes as necessary based 00323 // on imprinting. 00324 void CompositeEngine::attribute_after_imprinting(DLIList<TopologyBridge*> &tb_list, 00325 DLIList<Body*> &old_bodies) 00326 { 00327 DLIList<TopologyBridge*> all_bridges = tb_list; 00328 int i, j, k; 00329 for(k = old_bodies.size(); k>0; k--) 00330 { 00331 Body *body = old_bodies.get_and_step(); 00332 TopologyBridge *tb = body->bridge_manager()->topology_bridge(); 00333 if(tb) 00334 all_bridges.append_unique(tb); 00335 } 00336 00337 DLIList<Curve*> all_curves; 00338 DLIList<TBPoint*> all_points; 00339 get_all_curves_and_points(all_bridges, all_curves, all_points); 00340 all_curves.uniquify_ordered(); 00341 all_points.uniquify_ordered(); 00342 00343 double geom_factor = GeometryQueryTool::get_geometry_factor(); 00344 double merge_tol = geom_factor*GEOMETRY_RESABS; 00345 00346 AbstractTree<TBPoint*> *pt_tree = new RTree<TBPoint*>(merge_tol); 00347 AbstractTree<Curve*> *crv_tree = new RTree<Curve*>(merge_tol); 00348 00349 DLIList<Curve*> all_curves_with_composite_att; 00350 DLIList<TBPoint*> all_points_with_composite_att; 00351 for(k=all_curves.size(); k>0; k--) 00352 { 00353 Curve *cur_curve = all_curves.get_and_step(); 00354 crv_tree->add(cur_curve); 00355 DLIList<CubitSimpleAttrib> list; 00356 cur_curve->get_simple_attribute("COMPOSITE_GEOM",list); 00357 if(list.size() > 0) 00358 all_curves_with_composite_att.append(cur_curve); 00359 } 00360 for(k=all_points.size(); k>0; k--) 00361 { 00362 TBPoint *cur_point = all_points.get_and_step(); 00363 pt_tree->add(cur_point); 00364 DLIList<CubitSimpleAttrib> list; 00365 cur_point->get_simple_attribute("COMPOSITE_GEOM",list); 00366 if(list.size() > 0) 00367 all_points_with_composite_att.append(cur_point); 00368 } 00369 00370 DLIList<CubitSimpleAttrib> list; 00371 while(all_points_with_composite_att.size()) 00372 { 00373 DLIList<TBPoint*> other_pts; 00374 DLIList<BodySM*> other_bodies; 00375 DLIList<double> other_distances; 00376 00377 // For the given pt we will look for "coincident" pts (those within merge tol) 00378 // and categorize them as either having or not having a composite att. 00379 TBPoint *cur_pt = all_points_with_composite_att.extract(); 00380 pt_tree->remove(cur_pt); 00381 00382 BodySM *cur_body = cur_pt->bodysm(); 00383 DLIList<TBPoint*> coincident_pts_with_composite_att, coincident_pts_without_composite_att; 00384 DLIList<TBPoint*> close_pts; 00385 CubitBox bbox = cur_pt->bounding_box(); 00386 pt_tree->find(bbox, close_pts); 00387 00388 // Only keep the closest pt from each body. 00389 for(j=close_pts.size(); j>0; j--) 00390 { 00391 TBPoint *other_pt = close_pts.get_and_step(); 00392 BodySM *other_body = other_pt->bodysm(); 00393 // Don't keep anything that is in the same body as the current pt. 00394 if(other_body != cur_body) 00395 { 00396 double cur_dist_sq = cur_pt->coordinates().distance_between_squared(other_pt->coordinates()); 00397 if(other_bodies.move_to(other_body)) 00398 { 00399 int list_index = other_bodies.get_index(); 00400 other_distances.reset(); 00401 other_distances.step(list_index); 00402 double prev_dist_sq = other_distances.get(); 00403 if(cur_dist_sq < prev_dist_sq) 00404 { 00405 other_distances.change_to(cur_dist_sq); 00406 other_pts.reset(); 00407 other_pts.step(list_index); 00408 other_pts.change_to(other_pt); 00409 } 00410 } 00411 else 00412 { 00413 other_bodies.append(other_body); 00414 other_pts.append(other_pt); 00415 other_distances.append(cur_dist_sq); 00416 } 00417 } 00418 } 00419 // Make sure our current pt is added to a list. 00420 coincident_pts_with_composite_att.append(cur_pt); 00421 // Classify the coincident pts as either having or not 00422 // having a composite att. 00423 for(j=other_pts.size(); j>0; j--) 00424 { 00425 TBPoint *pt = other_pts.get_and_step(); 00426 list.clean_out(); 00427 pt->get_simple_attribute("COMPOSITE_GEOM",list); 00428 if(list.size() > 0) 00429 { 00430 coincident_pts_with_composite_att.append(pt); 00431 if(all_points_with_composite_att.move_to(pt)) 00432 all_points_with_composite_att.extract(); 00433 } 00434 else 00435 coincident_pts_without_composite_att.append(pt); 00436 } 00437 00438 // If we have found at least one other pt coincident with the current point... 00439 if(coincident_pts_with_composite_att.size() > 1 || 00440 coincident_pts_without_composite_att.size() > 0) 00441 { 00442 // If there is at least one pt without a composite att that is an imprinter we 00443 // will remove all composite atts from coincident pts 00444 bool found = false; 00445 for(j=coincident_pts_without_composite_att.size(); j>0 && !found; j--) 00446 { 00447 TBPoint *tmp_pt = coincident_pts_without_composite_att.get_and_step(); 00448 list.clean_out(); 00449 tmp_pt->get_simple_attribute("IMPRINTER",list); 00450 if(list.size() > 0) 00451 found = true; 00452 } 00453 if(found) 00454 { 00455 // Remove all composite atts. 00456 for(j=coincident_pts_with_composite_att.size(); j>0; j--) 00457 { 00458 TBPoint *tmp_pt = coincident_pts_with_composite_att.get_and_step(); 00459 list.clean_out(); 00460 tmp_pt->get_simple_attribute("COMPOSITE_GEOM",list); 00461 if(list.size() > 0) 00462 tmp_pt->remove_simple_attribute_virt(list.get()); 00463 } 00464 } 00465 else 00466 { 00467 // There were no imprinter points that didn't have composite atts. 00468 // Next we will look for imprinter points with composite atts. These 00469 // may have resulted in a new point. If there is a non composite att 00470 // point that doesn't have an ORIGINAL att we will know it is new 00471 // from the imprinter composite att point and we know to put a composite 00472 // att on it. 00473 found = false; 00474 for(j=coincident_pts_with_composite_att.size(); j>0 && !found; j--) 00475 { 00476 TBPoint *tmp_pt = coincident_pts_with_composite_att.get_and_step(); 00477 list.clean_out(); 00478 tmp_pt->get_simple_attribute("IMPRINTER",list); 00479 if(list.size() > 0) 00480 found = true; 00481 } 00482 if(found) 00483 { 00484 // Now put a composite att on any point that doesn't have one. 00485 for(j=coincident_pts_without_composite_att.size(); j>0; j--) 00486 { 00487 TBPoint *tmp_pt = coincident_pts_without_composite_att.get_and_step(); 00488 list.clean_out(); 00489 tmp_pt->get_simple_attribute("ORIGINAL", list); 00490 if(list.size() == 0) 00491 { 00492 // The point was not in the original model and therefore was created by 00493 // the imprint of a pt with a composite att. We need to put a composite 00494 // att on it. 00495 list.clean_out(); 00496 coincident_pts_with_composite_att.get()->get_simple_attribute("COMPOSITE_GEOM",list); 00497 tmp_pt->append_simple_attribute_virt(list.get()); 00498 } 00499 } 00500 } 00501 } 00502 } 00503 00504 for(i=coincident_pts_with_composite_att.size(); i>0; i--) 00505 { 00506 TBPoint *pt = coincident_pts_with_composite_att.get_and_step(); 00507 list.clean_out(); 00508 pt->get_simple_attribute("IMPRINTER",list); 00509 if(list.size() > 0) 00510 pt->remove_simple_attribute_virt(list.get()); 00511 list.clean_out(); 00512 pt->get_simple_attribute("ORIGINAL",list); 00513 if(list.size() > 0) 00514 pt->remove_simple_attribute_virt(list.get()); 00515 } 00516 for(i=coincident_pts_without_composite_att.size(); i>0; i--) 00517 { 00518 TBPoint *pt = coincident_pts_without_composite_att.get_and_step(); 00519 list.clean_out(); 00520 pt->get_simple_attribute("IMPRINTER",list); 00521 if(list.size() > 0) 00522 pt->remove_simple_attribute_virt(list.get()); 00523 list.clean_out(); 00524 pt->get_simple_attribute("ORIGINAL",list); 00525 if(list.size() > 0) 00526 pt->remove_simple_attribute_virt(list.get()); 00527 } 00528 } 00529 delete pt_tree; 00530 00531 CubitSense rel_sense; 00532 while(all_curves_with_composite_att.size()) 00533 { 00534 DLIList<Curve*> other_crvs; 00535 DLIList<BodySM*> other_bodies; 00536 DLIList<double> other_distances; 00537 00538 Curve *cur_crv = all_curves_with_composite_att.extract(); 00539 crv_tree->remove(cur_crv); 00540 00541 BodySM *cur_body = cur_crv->bodysm(); 00542 DLIList<Curve*> coincident_crvs_with_composite_att, coincident_crvs_without_composite_att; 00543 DLIList<Curve*> close_crvs; 00544 CubitBox bbox = cur_crv->bounding_box(); 00545 crv_tree->find(bbox, close_crvs); 00546 00547 for(j=close_crvs.size(); j>0; j--) 00548 { 00549 Curve *other_crv = close_crvs.get_and_step(); 00550 BodySM *other_body = other_crv->bodysm(); 00551 // Only consider curves from other bodies. 00552 if(cur_body != other_body) 00553 { 00554 if(this->about_spatially_equal(cur_crv, other_crv, rel_sense, geom_factor, 0)) 00555 { 00556 CubitVector pos1, pos2; 00557 double cur_dist; 00558 cur_crv->get_geometry_query_engine()->entity_entity_distance( 00559 cur_crv, other_crv, pos1, pos2, cur_dist ); 00560 if(other_bodies.move_to(other_body)) 00561 { 00562 int list_index = other_bodies.get_index(); 00563 other_distances.reset(); 00564 other_distances.step(list_index); 00565 double prev_dist = other_distances.get(); 00566 if(cur_dist < prev_dist) 00567 { 00568 other_distances.change_to(cur_dist); 00569 other_crvs.reset(); 00570 other_crvs.step(list_index); 00571 other_crvs.change_to(other_crv); 00572 } 00573 } 00574 else 00575 { 00576 other_bodies.append(other_body); 00577 other_crvs.append(other_crv); 00578 other_distances.append(cur_dist); 00579 } 00580 } 00581 } 00582 coincident_crvs_with_composite_att.append(cur_crv); 00583 for(j=other_crvs.size(); j>0; j--) 00584 { 00585 Curve *crv = other_crvs.get_and_step(); 00586 list.clean_out(); 00587 crv->get_simple_attribute("COMPOSITE_GEOM", list); 00588 if(list.size() > 0) 00589 { 00590 coincident_crvs_with_composite_att.append(other_crv); 00591 if(all_curves_with_composite_att.move_to(other_crv)) 00592 all_curves_with_composite_att.extract(); 00593 } 00594 else 00595 coincident_crvs_without_composite_att.append(other_crv); 00596 } 00597 } 00598 00599 // If we have found at least one other crv coincident with the current crv... 00600 if(coincident_crvs_with_composite_att.size() > 1 || 00601 coincident_crvs_without_composite_att.size() > 0) 00602 { 00603 // If there is at least one curve without a composite att that is an imprinter we 00604 // will remove all composite atts from coincident curves 00605 bool found = false; 00606 for(j=coincident_crvs_without_composite_att.size(); j>0 && !found; j--) 00607 { 00608 Curve *tmp_crv = coincident_crvs_without_composite_att.get_and_step(); 00609 list.clean_out(); 00610 tmp_crv->get_simple_attribute("IMPRINTER",list); 00611 if(list.size() > 0) 00612 found = true; 00613 } 00614 if(found) 00615 { 00616 // Remove all composite atts. 00617 for(j=coincident_crvs_with_composite_att.size(); j>0; j--) 00618 { 00619 Curve *tmp_crv = coincident_crvs_with_composite_att.get_and_step(); 00620 list.clean_out(); 00621 tmp_crv->get_simple_attribute("COMPOSITE_GEOM",list); 00622 if(list.size() > 0) 00623 tmp_crv->remove_simple_attribute_virt(list.get()); 00624 } 00625 } 00626 else 00627 { 00628 // There were no imprinter crvs that didn't have composite atts. 00629 // Next we will look for imprinter crvs with composite atts. These 00630 // may have resulted in a new crv. If there is a non composite att 00631 // crv that doesn't have an ORIGINAL att we will know it is new 00632 // from the imprinter composite att crv and we know to put a composite 00633 // att on it. 00634 found = false; 00635 for(j=coincident_crvs_with_composite_att.size(); j>0 && !found; j--) 00636 { 00637 Curve *tmp_crv = coincident_crvs_with_composite_att.get_and_step(); 00638 list.clean_out(); 00639 tmp_crv->get_simple_attribute("IMPRINTER",list); 00640 if(list.size() > 0) 00641 found = true; 00642 } 00643 if(found) 00644 { 00645 // Now put a composite att on any crv that doesn't have one. 00646 for(j=coincident_crvs_without_composite_att.size(); j>0; j--) 00647 { 00648 Curve *tmp_crv = coincident_crvs_without_composite_att.get_and_step(); 00649 list.clean_out(); 00650 tmp_crv->get_simple_attribute("ORIGINAL", list); 00651 if(list.size() == 0) 00652 { 00653 // The crv was not in the original model and therefore was created by 00654 // the imprint of a crv with a composite att. We need to put a composite 00655 // att on it. 00656 list.clean_out(); 00657 coincident_crvs_with_composite_att.get()->get_simple_attribute("COMPOSITE_GEOM",list); 00658 tmp_crv->append_simple_attribute_virt(list.get()); 00659 } 00660 } 00661 } 00662 } 00663 } 00664 00665 for(i=coincident_crvs_with_composite_att.size(); i>0; i--) 00666 { 00667 Curve *crv = coincident_crvs_with_composite_att.get_and_step(); 00668 list.clean_out(); 00669 crv->get_simple_attribute("IMPRINTER",list); 00670 if(list.size() > 0) 00671 crv->remove_simple_attribute_virt(list.get()); 00672 list.clean_out(); 00673 crv->get_simple_attribute("ORIGINAL",list); 00674 if(list.size() > 0) 00675 crv->remove_simple_attribute_virt(list.get()); 00676 } 00677 for(i=coincident_crvs_without_composite_att.size(); i>0; i--) 00678 { 00679 Curve *crv = coincident_crvs_without_composite_att.get_and_step(); 00680 list.clean_out(); 00681 crv->get_simple_attribute("IMPRINTER",list); 00682 if(list.size() > 0) 00683 crv->remove_simple_attribute_virt(list.get()); 00684 list.clean_out(); 00685 crv->get_simple_attribute("ORIGINAL",list); 00686 if(list.size() > 0) 00687 crv->remove_simple_attribute_virt(list.get()); 00688 } 00689 } 00690 delete crv_tree; 00691 for(i=all_curves.size(); i>0; i--) 00692 { 00693 Curve *cur_curve = all_curves.get_and_step(); 00694 list.clean_out(); 00695 cur_curve->get_simple_attribute("IMPRINTER",list); 00696 if(list.size() > 0) 00697 cur_curve->remove_simple_attribute_virt(list.get()); 00698 list.clean_out(); 00699 cur_curve->get_simple_attribute("ORIGINAL",list); 00700 if(list.size() > 0) 00701 cur_curve->remove_simple_attribute_virt(list.get()); 00702 } 00703 for(i=all_points.size(); i>0; i--) 00704 { 00705 TBPoint *cur_point = all_points.get_and_step(); 00706 list.clean_out(); 00707 cur_point->get_simple_attribute("IMPRINTER",list); 00708 if(list.size() > 0) 00709 cur_point->remove_simple_attribute_virt(list.get()); 00710 list.clean_out(); 00711 cur_point->get_simple_attribute("ORIGINAL",list); 00712 if(list.size() > 0) 00713 cur_point->remove_simple_attribute_virt(list.get()); 00714 } 00715 } 00716 00717 void CompositeEngine::process_curves_after_imprint(Curve *att_cur, 00718 Curve *other_cur, 00719 DLIList<BodySM*> &new_sms) 00720 { 00721 DLIList<CubitSimpleAttrib> list; 00722 00723 if(att_cur == other_cur) 00724 { 00725 // This case will happen when we have manually added one of the existing 00726 // curves on the surface to be imprinted to the "new_ENTITIES" list. We 00727 // do this in cases where the curve to imprint on the surface exactly 00728 // falls on one of the existing curves. In this case the face 00729 // doesn't get new curves created but we need to consider the 00730 // curve on the face as new because it may have been hidden in a 00731 // composite surface and needs to be reintroduced. So, in this 00732 // case we will remove the attribute so that the curve is no longer 00733 // hidden. 00734 att_cur->get_simple_attribute("COMPOSITE_GEOM",list); 00735 att_cur->remove_simple_attribute_virt(list.get()); 00736 } 00737 else 00738 { 00739 other_cur->get_simple_attribute("IMPRINT_PREEXISTING",list); 00740 if(list.size() == 0) 00741 { 00742 // This is a new bridge created by imprinting this hidden bridge. In 00743 // this case we need to add a COMPOSITE_GEOM attribute to the new bridge 00744 // so we don't see a resulting imprinted bridge from the hidden bridge. 00745 list.clean_out(); 00746 att_cur->get_simple_attribute("COMPOSITE_GEOM",list); 00747 other_cur->append_simple_attribute_virt(list.get()); 00748 } 00749 else 00750 { 00751 // This bridge existed before the imprint operation. Therefore it 00752 // could also have a COMPOSITE_GEOM attribute on it. Check this. 00753 list.clean_out(); 00754 other_cur->get_simple_attribute("COMPOSITE_GEOM",list); 00755 if(list.size() == 0) 00756 { 00757 // It doesn't have a COMPOSITE_GEOM attribute so we need to remove 00758 // the COMPOSITE_GEOM from att_bridge because the hidden nature gets 00759 // wiped out by the imprinting process. 00760 att_cur->get_simple_attribute("COMPOSITE_GEOM",list); 00761 att_cur->remove_simple_attribute_virt(list.get()); 00762 TBOwner *bridge_owner = att_cur->owner(); 00763 CompositeCurve *cc_bridge_owner = dynamic_cast<CompositeCurve*>(bridge_owner); 00764 if(cc_bridge_owner) 00765 { 00766 TBOwner *cc_owner = cc_bridge_owner->owner(); 00767 HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(cc_owner); 00768 if(hes) 00769 { 00770 CompositeSurface *cs = dynamic_cast<CompositeSurface*>(hes->owner()); 00771 if(cs) 00772 cs->HadBridgeRemoved = 1; 00773 // This is currently how we are notifying the owning CompositeSurface 00774 // that it needs to be deactivated and rebuilt. It really has 00775 // nothing to do with the bridge being removed though. Bad. 00776 } 00777 } 00778 } 00779 else 00780 { 00781 // This bridge was also hidden so do nothing. 00782 } 00783 } 00784 } 00785 } 00786 00787 void CompositeEngine::process_points_after_imprint(TBPoint *att_pt, 00788 TBPoint *other_pt, 00789 DLIList<BodySM*> &new_sms) 00790 { 00791 int i; 00792 DLIList<CubitSimpleAttrib> list; 00793 00794 if(att_pt == other_pt) 00795 { 00796 // This case will happen when we have manually added one of the existing 00797 // pts on the surface to be imprinted to the "new_ENTITIES" list. We 00798 // do this in cases where the pt to imprint on the surface exactly 00799 // falls on one of the existing pts. In this case the face 00800 // doesn't get new pts created but we need to consider the 00801 // pt on the face as new because it may have been hidden in a 00802 // composite curve and needs to be reintroduced. So, in this 00803 // case we will remove the attribute so that the pt is no longer 00804 // hidden. 00805 att_pt->get_simple_attribute("COMPOSITE_GEOM",list); 00806 att_pt->remove_simple_attribute_virt(list.get()); 00807 } 00808 else 00809 { 00810 other_pt->get_simple_attribute("IMPRINT_PREEXISTING",list); 00811 if(list.size() == 0) 00812 { 00813 // This is a new bridge created by imprinting this hidden bridge. In 00814 // this case we need to add a COMPOSITE_GEOM attribute to the new bridge 00815 // if possible so we don't see a resulting imprinted bridge from the hidden bridge. 00816 int num_visible_curves = 0; 00817 DLIList<TopologyBridge*> curves; 00818 att_pt->get_parents_virt(curves); 00819 for(i=curves.size(); i--;) 00820 { 00821 list.clean_out(); 00822 TopologyBridge *c = curves.get_and_step(); 00823 c->get_simple_attribute("COMPOSITE_GEOM", list); 00824 if(list.size() == 0) 00825 num_visible_curves++; 00826 } 00827 if(num_visible_curves > 2) 00828 { 00829 list.clean_out(); 00830 att_pt->get_simple_attribute("COMPOSITE_GEOM",list); 00831 att_pt->remove_simple_attribute_virt(list.get()); 00832 TBOwner *bridge_owner = att_pt->owner(); 00833 CompositePoint *cp_bridge_owner = dynamic_cast<CompositePoint*>(bridge_owner); 00834 if(cp_bridge_owner) 00835 { 00836 TBOwner *cp_owner = cp_bridge_owner->owner(); 00837 HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(cp_owner); 00838 if(hes) 00839 { 00840 CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hes->owner()); 00841 if(cc) 00842 cc->HadBridgeRemoved = 1; 00843 // This is currently how we are notifying the owning CompositeCurve 00844 // that it needs to be deactivated and rebuilt. It really has 00845 // nothing to do with the bridge being removed though. Bad. 00846 } 00847 } 00848 } 00849 else 00850 { 00851 list.clean_out(); 00852 att_pt->get_simple_attribute("COMPOSITE_GEOM",list); 00853 other_pt->append_simple_attribute_virt(list.get()); 00854 } 00855 } 00856 else 00857 { 00858 // This bridge existed before the imprint operation. Therefore it 00859 // could also have a COMPOSITE_GEOM attribute on it. Check this. 00860 list.clean_out(); 00861 other_pt->get_simple_attribute("COMPOSITE_GEOM",list); 00862 if(list.size() == 0) 00863 { 00864 // It doesn't have a COMPOSITE_GEOM attribute so we need to remove 00865 // the COMPOSITE_GEOM from att_bridge because the hidden nature gets 00866 // wiped out by the imprinting process. 00867 att_pt->get_simple_attribute("COMPOSITE_GEOM",list); 00868 att_pt->remove_simple_attribute_virt(list.get()); 00869 TBOwner *bridge_owner = att_pt->owner(); 00870 CompositePoint *cp_bridge_owner = dynamic_cast<CompositePoint*>(bridge_owner); 00871 if(cp_bridge_owner) 00872 { 00873 TBOwner *cp_owner = cp_bridge_owner->owner(); 00874 HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(cp_owner); 00875 if(hes) 00876 { 00877 CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hes->owner()); 00878 if(cc) 00879 cc->HadBridgeRemoved = 1; 00880 // This is currently how we are notifying the owning CompositeCurve 00881 // that it needs to be deactivated and rebuilt. It really has 00882 // nothing to do with the bridge being removed though. Bad. 00883 } 00884 } 00885 } 00886 else 00887 { 00888 // This bridge was also hidden so do nothing. 00889 } 00890 } 00891 } 00892 } 00893 00894 // This is a copy of the function in MergeTool with the difference that it 00895 // accepts a layer flag to dictate at which level the topology is traversed 00896 // (solid modeler level or virtual level). 00897 CubitBoolean CompositeEngine::about_spatially_equal( Curve *curve_1, Curve *curve_2, 00898 CubitSense &relative_sense, 00899 double tolerance_factor, 00900 int layer) 00901 { 00902 if( curve_1 == curve_2 ) 00903 return CUBIT_TRUE; 00904 00905 relative_sense = CUBIT_FORWARD; 00906 const double ONE_THIRD = 1.0/3.0; 00907 00908 // Find the point 1/3 along curve_1 00909 CubitVector test_point_1, test_point_2; 00910 if( curve_1->position_from_fraction( ONE_THIRD, test_point_1 ) != CUBIT_SUCCESS ) 00911 return CUBIT_FALSE; 00912 00913 // See if the 1/3 point on curve_1 lies on curve_2 00914 if ( curve_2->closest_point_trimmed(test_point_1, test_point_2) 00915 != CUBIT_SUCCESS ) 00916 { 00917 return CUBIT_FALSE; 00918 } 00919 00920 if ( GeometryQueryTool::instance()-> 00921 about_spatially_equal(test_point_1, test_point_2, tolerance_factor ) 00922 != CUBIT_SUCCESS ) 00923 { 00924 return CUBIT_FALSE; 00925 } 00926 00927 CubitVector tangent_1, tangent_2; 00928 if( curve_1->closest_point(test_point_2, test_point_1, &tangent_1) != CUBIT_SUCCESS ) 00929 return CUBIT_FALSE; 00930 if( curve_2->closest_point(test_point_1, test_point_2, &tangent_2) != CUBIT_SUCCESS ) 00931 return CUBIT_FALSE; 00932 00933 //If one of the curves is zero-length, it will have a zero 00934 //tangent vector. 00935 double len_product = tangent_1.length() * tangent_2.length(); 00936 if( len_product > CUBIT_DBL_MIN ) 00937 { 00938 double dot_product = (tangent_1 % tangent_2); 00939 if (dot_product < 0) 00940 relative_sense = CUBIT_REVERSED; 00941 } 00942 else 00943 { 00944 //If one of the tangents is zero-length, one of the curves had 00945 //better be as well. 00946 assert( (curve_1->measure() * curve_2->measure()) < CUBIT_RESABS ); 00947 } 00948 00949 //compare the start and end vertices to be spatially equal. 00950 DLIList<TBPoint*> curve_1_points(2), curve_2_points(2); 00951 DLIList<TopologyBridge*> c1pts, c2pts; 00952 curve_1->get_children(c1pts, false, layer); 00953 curve_2->get_children(c2pts, false, layer); 00954 CAST_LIST( c1pts, curve_1_points, TBPoint ); 00955 CAST_LIST( c2pts, curve_2_points, TBPoint ); 00956 00957 if( curve_1->bridge_sense() == CUBIT_REVERSED ) 00958 curve_1_points.reverse(); 00959 if( curve_2->bridge_sense() == CUBIT_REVERSED ) 00960 curve_2_points.reverse(); 00961 00962 TBPoint* curve_1_start = curve_1_points.get(); 00963 curve_1_points.last(); 00964 TBPoint* curve_1_end = curve_1_points.get(); 00965 00966 TBPoint* curve_2_start = curve_2_points.get(); 00967 curve_2_points.last(); 00968 TBPoint* curve_2_end = curve_2_points.get(); 00969 00970 if (relative_sense == CUBIT_REVERSED) 00971 std::swap(curve_2_start, curve_2_end); 00972 00973 if (curve_1_start == curve_1_end ||curve_2_start == curve_2_end) 00974 { 00975 CubitVector c1start = curve_1_start->coordinates(); 00976 CubitVector c2start = curve_2_start->coordinates(); 00977 if ((curve_1_start != curve_1_end) || 00978 (curve_2_start != curve_2_end) || 00979 !GeometryQueryTool::instance()->about_spatially_equal(c1start, c2start, tolerance_factor)) 00980 return CUBIT_FALSE; 00981 } 00982 else 00983 { 00984 CubitVector c1start = curve_1_start->coordinates(); 00985 CubitVector c1end = curve_1_end->coordinates(); 00986 CubitVector c2start = curve_2_start->coordinates(); 00987 CubitVector c2end = curve_2_end->coordinates(); 00988 if ((curve_1_start == curve_2_end) || 00989 (curve_1_end == curve_2_start) || 00990 !GeometryQueryTool::instance()->about_spatially_equal(c1start, c2start, tolerance_factor ) || 00991 !GeometryQueryTool::instance()->about_spatially_equal(c1end, c2end, tolerance_factor )) 00992 return CUBIT_FALSE; 00993 } 00994 00995 return CUBIT_TRUE; 00996 00997 } 00998 00999 // This function will try to determine if virtual topology bridges have 01000 // been modified and if so will deactivate them so that they can be 01001 // rebuilt later using the COMPOSITE_GEOM attributes on the underlying 01002 // solid model topology. 01003 void CompositeEngine::remove_modified(DLIList<Surface*> &surfaces, 01004 DLIList<Curve*> &curves, 01005 DLIList<TBPoint*> &points) 01006 { 01007 clean_out_deactivated_geometry(); 01008 01009 int i, j, k, m, n, w; 01010 int something_changed = 1; 01011 DLIList<TBPoint*> already_deactivated_points; 01012 DLIList<Curve*> already_deactivated_curves; 01013 DLIList<Surface*> already_deactivated_surfs; 01014 01015 while(something_changed) 01016 { 01017 something_changed = 0; 01018 01019 DLIList<TBPoint*> deactivated_points; 01020 DLIList<Curve*> deactivated_curves; 01021 DLIList<Surface*> deactivated_surfs; 01022 01023 // Look for composite points that are out of date. 01024 for(w=points.size(); w--;) 01025 { 01026 CompositePoint *p = dynamic_cast<CompositePoint*>(points.get_and_step()); 01027 if(p && !already_deactivated_points.is_in_list(p)) 01028 deactivated_points.append(p); 01029 } 01030 deactivated_points.uniquify_ordered(); 01031 01032 // Look for composite curves that are out of date. 01033 for(w=curves.size(); w--;) 01034 { 01035 Curve *current_curve = curves.get_and_step(); 01036 CompositeCurve *cur = dynamic_cast<CompositeCurve*>(current_curve); 01037 if(cur && !already_deactivated_curves.is_in_list(cur)) 01038 deactivated_curves.append(cur); 01039 } 01040 deactivated_curves.uniquify_ordered(); 01041 01042 // Look for composite surfaces that are out of date. 01043 for(w=surfaces.size(); w--;) 01044 { 01045 CompositeSurface* csurf = dynamic_cast<CompositeSurface*> (surfaces.get_and_step()); 01046 if (csurf && !already_deactivated_surfs.is_in_list(csurf)) 01047 deactivated_surfs.append(csurf); 01048 } 01049 deactivated_surfs.uniquify_ordered(); 01050 01051 already_deactivated_points += deactivated_points; 01052 already_deactivated_curves += deactivated_curves; 01053 already_deactivated_surfs += deactivated_surfs; 01054 01055 something_changed += deactivated_surfs.size() + deactivated_curves.size() + 01056 deactivated_points.size(); 01057 01058 // Now actually deactivate the out of date composite surfs. 01059 for(j=deactivated_surfs.size(); j--;) 01060 { 01061 CompositeSurface *csurf = dynamic_cast<CompositeSurface*>(deactivated_surfs.get_and_step()); 01062 01063 // We have to also deactivate the boundary curves. When we deactivate 01064 // the CompositeSurface it removes all of the CompositeCoEdges associated 01065 // with it. However, it doesn't deactivate the composite curves associated 01066 // with the composite coedges. Therefore you can end up with a regular 01067 // CoEdge pointing to a CompositeCurve and if the CompositeCurve has more 01068 // than 1 curve in it later calls to replace_surface (which will in turn 01069 // call replace_curve) will fail. 01070 DLIList<Curve*> boundary_curves; 01071 csurf->curves(boundary_curves); 01072 for (k=boundary_curves.size(); k--; ) 01073 { 01074 CompositeCurve* c = dynamic_cast<CompositeCurve*>(boundary_curves.get_and_step()); 01075 assert(NULL != c); 01076 deactivated_curves.append_unique(c); 01077 already_deactivated_curves.append_unique(c); 01078 01079 DLIList<TBPoint*> boundary_pts; 01080 c->points(boundary_pts); 01081 for (int e=boundary_pts.size(); e--; ) 01082 { 01083 CompositePoint* p = dynamic_cast<CompositePoint*>(boundary_pts.get_and_step()); 01084 deactivated_points.append_unique(p); 01085 already_deactivated_points.append_unique(p); 01086 notify_deactivated(p); 01087 } 01088 01089 notify_deactivated(c); 01090 } 01091 01092 notify_deactivated(csurf); 01093 01094 DLIList<Curve*> hidden; 01095 csurf->get_hidden_curves(hidden); 01096 for (k=hidden.size(); k--; ) 01097 { 01098 CompositeCurve* hcurve = dynamic_cast<CompositeCurve*>(hidden.pop()); 01099 assert(NULL != hcurve); 01100 01101 deactivated_curves.append_unique(hcurve); 01102 already_deactivated_curves.append_unique(hcurve); 01103 notify_deactivated(hcurve); 01104 01105 if(hcurve->num_curves() == 1) 01106 { 01107 Curve *c = hcurve->get_curve(0); 01108 DLIList<TopologyBridge*> end_pts; 01109 c->get_children(end_pts, false, 0); 01110 for(m=end_pts.size(); m--;) 01111 { 01112 TBPoint *cur_p = dynamic_cast<TBPoint*>(end_pts.get_and_step()); 01113 if(cur_p) 01114 { 01115 CompositePoint* cp = dynamic_cast<CompositePoint*>(cur_p->owner()); 01116 if(cp) 01117 cur_p = (TBPoint*)cp; 01118 TBOwner *own = cur_p->owner(); 01119 HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(own); 01120 if(hes) 01121 { 01122 CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hes->owner()); 01123 if(cc) 01124 { 01125 deactivated_curves.append_unique(cc); 01126 already_deactivated_curves.append_unique(cc); 01127 notify_deactivated(cc); 01128 01129 DLIList<TBPoint*> hidden_pts; 01130 cc->get_hidden_points(hidden_pts); 01131 for (n=hidden_pts.size(); n--; ) 01132 { 01133 CompositePoint *hpoint = dynamic_cast<CompositePoint*>(hidden_pts.pop()); 01134 assert(NULL != hpoint); 01135 deactivated_points.append_unique(hpoint); 01136 already_deactivated_points.append_unique(hpoint); 01137 notify_deactivated(hpoint); 01138 } 01139 } 01140 } 01141 } 01142 } 01143 } 01144 } 01145 } 01146 01147 // Now actually deactivate the out of date composite curves. 01148 for(j=deactivated_curves.size(); j--;) 01149 { 01150 CompositeCurve *ccurve = dynamic_cast<CompositeCurve*>(deactivated_curves.get_and_step()); 01151 01152 DLIList<TBPoint*> boundary_pts; 01153 ccurve->points(boundary_pts); 01154 for (k=boundary_pts.size(); k--; ) 01155 { 01156 CompositePoint* p = dynamic_cast<CompositePoint*>(boundary_pts.get_and_step()); 01157 deactivated_points.append_unique(p); 01158 already_deactivated_points.append_unique(p); 01159 notify_deactivated(p); 01160 } 01161 01162 notify_deactivated(ccurve); 01163 01164 int j; 01165 DLIList<TBPoint*> hidden; 01166 ccurve->get_hidden_points(hidden); 01167 for (j=hidden.size(); j--; ) 01168 { 01169 CompositePoint *hpoint = dynamic_cast<CompositePoint*>(hidden.pop()); 01170 assert(NULL != hpoint); 01171 deactivated_points.append_unique(hpoint); 01172 already_deactivated_points.append_unique(hpoint); 01173 notify_deactivated(hpoint); 01174 } 01175 } 01176 01177 // Now actually deactivate the out of date composite points. 01178 for(j=deactivated_points.size(); j--;) 01179 { 01180 CompositePoint* cpoint = dynamic_cast<CompositePoint*> (deactivated_points.pop()); 01181 notify_deactivated(cpoint); 01182 } 01183 } 01184 01185 int remove_point_atts = 1; 01186 if(remove_point_atts) 01187 { 01188 // Remove any COMPOSITE_GEOM attributes on points that 01189 // have a valence of more than two (real curves - hidden curves). 01190 for(i=points.size(); i>0; i--) 01191 { 01192 TBPoint *pt = points.get_and_step(); 01193 CompositePoint *cp = dynamic_cast<CompositePoint*>(pt); 01194 if(cp) 01195 pt = cp->get_point(); 01196 DLIList<CubitSimpleAttrib> attribs; 01197 pt->get_simple_attribute("COMPOSITE_GEOM", attribs); 01198 if(attribs.size() > 0) 01199 { 01200 DLIList<TopologyBridge*> tmp_curves; 01201 pt->get_parents_virt(tmp_curves); 01202 int num_curves = 0; 01203 for(j=tmp_curves.size(); j>0; j--) 01204 { 01205 TopologyBridge *crv = tmp_curves.get_and_step(); 01206 DLIList<CubitSimpleAttrib> attribs; 01207 crv->get_simple_attribute("COMPOSITE_GEOM", attribs); 01208 if(attribs.size() == 0) 01209 num_curves++; 01210 } 01211 if(num_curves != 2) 01212 { 01213 for(j=attribs.size(); j>0; j--) 01214 { 01215 const CubitSimpleAttrib &csa = attribs.get_and_step(); 01216 pt->remove_simple_attribute_virt(csa); 01217 } 01218 } 01219 } 01220 } 01221 } 01222 } 01223 01224 //------------------------------------------------------------------------- 01225 // Purpose : Constructor 01226 // 01227 // Special Notes : 01228 // 01229 // Creator : Jason Kraftcheck 01230 // 01231 // Creation Date : 08/25/03 01232 //------------------------------------------------------------------------- 01233 CompositeEngine::CompositeEngine() 01234 { 01235 CubitStatus result = GeometryQueryTool::instance()-> 01236 register_intermediate_engine( this ); 01237 assert(result == CUBIT_SUCCESS); 01238 if (CUBIT_SUCCESS != result) { 01239 PRINT_ERROR("Failed to register intermediate engine.\n"); 01240 } 01241 } 01242 01243 //------------------------------------------------------------------------- 01244 // Purpose : Get composite-level query results from 01245 // query of underlying topology. 01246 // 01247 // Special Notes : 01248 // 01249 // Creator : Jason Kraftcheck 01250 // 01251 // Creation Date : 03/13/02 01252 //------------------------------------------------------------------------- 01253 /* 01254 void CompositeEngine::fix_up_query_results( DLIList<TopologyBridge*>& list, 01255 bool keep_hidden ) 01256 { 01257 DLIList<TopologyBridge*> tmp_list; 01258 int i; 01259 01260 list.reset(); 01261 for( i = list.size(); i--; ) 01262 { 01263 TopologyBridge* bridge = list.get(); 01264 TBOwnerSet* set = dynamic_cast<TBOwnerSet*>(bridge->owner()); 01265 if( set ) 01266 { 01267 tmp_list.clean_out(); 01268 set->get_owners( tmp_list ); 01269 if( tmp_list.size() ) 01270 { 01271 tmp_list.reset(); 01272 list.change_to( tmp_list.get_and_step() ); 01273 for( int j = 1; j < tmp_list.size(); j++ ) 01274 list.insert( tmp_list.get_and_step() ); 01275 } 01276 else 01277 { 01278 list.change_to(0); 01279 } 01280 } 01281 list.step(); 01282 } 01283 01284 list.remove_all_with_value( 0 ); 01285 01286 list.reset(); 01287 for( i = list.size(); i--; ) 01288 { 01289 TopologyBridge* bridge = list.get(); 01290 TopologyBridge *next = 0; 01291 while( next = dynamic_cast<TopologyBridge*>(bridge->owner()) ) 01292 bridge = next; 01293 01294 if( !keep_hidden && dynamic_cast<HiddenEntitySet*>(bridge->owner()) ) 01295 { 01296 list.change_to(0); 01297 } 01298 else if( list.get() != bridge ) 01299 { 01300 if( list.is_in_list( bridge ) ) 01301 list.change_to(0); 01302 else 01303 list.change_to(bridge); 01304 } 01305 01306 list.step(); 01307 } 01308 01309 list.remove_all_with_value( 0 ); 01310 } 01311 */ 01312 01313 01314 //------------------------------------------------------------------------- 01315 // Purpose : Combine two curves 01316 // 01317 // Special Notes : 01318 // 01319 // Creator : Jason Kraftcheck 01320 // 01321 // Creation Date : 03/13/02 01322 //------------------------------------------------------------------------- 01323 CompositeCurve* CompositeEngine::composite( Curve* keep_curve, 01324 Curve* dead_curve, 01325 TBPoint* keep_point, 01326 bool remove_partition ) 01327 { 01328 if( keep_curve == dead_curve ) 01329 { 01330 PRINT_ERROR("Cannot remove vertex from single-vertex curve.\n"); 01331 return 0; 01332 } 01333 01334 CompositeCurve* result = 0; 01335 CompositeCurve* ckeep = dynamic_cast<CompositeCurve*>(keep_curve); 01336 CompositeCurve* cdead = dynamic_cast<CompositeCurve*>(dead_curve); 01337 bool replaced1 = false; 01338 bool replaced2 = false; 01339 01340 if( !ckeep ) 01341 { 01342 ckeep = replace_curve( keep_curve ); 01343 replaced1 = true; 01344 } 01345 if( !cdead ) 01346 { 01347 cdead = replace_curve( dead_curve ); 01348 replaced2 = true; 01349 } 01350 01351 CompositePoint* comppoint = dynamic_cast<CompositePoint*>(keep_point); 01352 if( keep_point && !comppoint ) 01353 { 01354 comppoint = dynamic_cast<CompositePoint*>(keep_point->owner()); 01355 assert( comppoint!= NULL ); 01356 } 01357 01358 if( !ckeep || !cdead || 01359 !(result = combine(ckeep, cdead, comppoint, remove_partition)) ) 01360 { 01361 if( replaced1 && ckeep ) 01362 { 01363 Curve* s = remove_composite( ckeep ); 01364 assert( s != 0 ); 01365 if (NULL == s) { 01366 PRINT_ERROR("Failed to remove a 1-curve composite.\n"); 01367 return NULL; 01368 } 01369 } 01370 if( replaced2 && cdead ) 01371 { 01372 Curve* s = remove_composite( cdead ); 01373 assert( s != 0 ); 01374 if (NULL == s) { 01375 PRINT_ERROR("Failed to remove a 1-curve composite.\n"); 01376 return NULL; 01377 } 01378 } 01379 } 01380 01381 return result; 01382 } 01383 01384 //------------------------------------------------------------------------- 01385 // Purpose : Replace a "point" curve with a composite 01386 // 01387 // Special Notes : 01388 // 01389 // Creator : Jason Kraftcheck 01390 // 01391 // Creation Date : 11/26/02 01392 //------------------------------------------------------------------------- 01393 CompositePoint* CompositeEngine::replace_point( TBPoint* point ) 01394 { 01395 assert( !dynamic_cast<CompositePoint*>(point) ); 01396 return new CompositePoint( point ); 01397 } 01398 01399 //------------------------------------------------------------------------- 01400 // Purpose : Replace a "real" curve with a composite 01401 // 01402 // Special Notes : 01403 // 01404 // Creator : Jason Kraftcheck 01405 // 01406 // Creation Date : 03/13/02 01407 //------------------------------------------------------------------------- 01408 CompositeCurve* CompositeEngine::replace_curve( Curve* curve ) 01409 { 01410 DLIList<TopologyBridge*> points, coedges; 01411 //curve->get_children_virt( points ); 01412 //fix_up_query_results(points); 01413 curve->get_children( points, true, COMPOSITE_LAYER ); 01414 01415 if(points.size() > 2) 01416 return 0; 01417 01418 points.reset(); 01419 TBPoint* start_pt = dynamic_cast<TBPoint*>(points.get_and_step()); 01420 TBPoint* end_pt = dynamic_cast<TBPoint*>(points.get_and_step()); 01421 01422 CompositeCurve* composite = dynamic_cast<CompositeCurve*>(curve); 01423 01424 if(!composite) 01425 composite = new CompositeCurve( curve ); 01426 else 01427 { 01428 if(composite->num_curves() > 1) 01429 { 01430 PRINT_ERROR("Error replacing existing composite curve with more than one underlying curve\n"); 01431 return 0; 01432 } 01433 } 01434 01435 CompositePoint* start = dynamic_cast<CompositePoint*>(start_pt); 01436 if( !start ) 01437 start = replace_point( start_pt ); 01438 CompositePoint* end = 0; 01439 if ( end_pt == start_pt ) 01440 end = start; 01441 else if ( !(end = dynamic_cast<CompositePoint*>(end_pt)) ) 01442 end = replace_point( end_pt ); 01443 assert( start && end ); 01444 01445 composite->start_point( start ); 01446 composite-> end_point( end ); 01447 01448 DLIList<TopologyBridge*> existing_composite_coedges; 01449 if(dynamic_cast<CompositeCurve*>(curve)) 01450 { 01451 dynamic_cast<CompositeCurve*>(curve)->get_curve(0)->get_parents_virt(coedges); 01452 curve->get_parents_virt(existing_composite_coedges); 01453 } 01454 else 01455 { 01456 curve->get_parents_virt( coedges ); 01457 } 01458 for( int i = coedges.size(); i--; ) 01459 { 01460 CoEdgeSM* coedge = dynamic_cast<CoEdgeSM*>(coedges.get_and_step()); 01461 assert(coedge); 01462 CompositeCoEdge* ccoedge = NULL; 01463 for(int h=existing_composite_coedges.size(); h>0; h--) 01464 { 01465 CompositeCoEdge *temp = dynamic_cast<CompositeCoEdge*>(existing_composite_coedges.get_and_step()); 01466 if(temp->get_coedge(0) == coedge) 01467 { 01468 ccoedge = temp; 01469 h = 0; 01470 } 01471 } 01472 if(!ccoedge) 01473 { 01474 ccoedge = new CompositeCoEdge( coedge ); 01475 if( composite->get_sense(0) == CUBIT_REVERSED ) 01476 ccoedge->reverse(); 01477 01478 assert( ccoedge->get_curve() == 0 ); 01479 composite->add( ccoedge ); 01480 } 01481 } 01482 01483 return composite; 01484 } 01485 01486 01487 //------------------------------------------------------------------------- 01488 // Purpose : Replace a "real" surface with a composite 01489 // 01490 // Special Notes : 01491 // 01492 // Creator : Jason Kraftcheck 01493 // 01494 // Creation Date : 03/13/02 01495 //------------------------------------------------------------------------- 01496 CompositeSurface* CompositeEngine::replace_surface( Surface* surface ) 01497 { 01498 DLIList<TopologyBridge*> loops, coedges, curves; 01499 int i, j; 01500 if( dynamic_cast<CompositeSurface*>(surface) ) 01501 return 0; 01502 01503 CompositeSurface* compsurf = new CompositeSurface( surface ); 01504 //surface->get_children_virt( loops ); 01505 //fix_up_query_results(loops); 01506 surface->get_children( loops, false, COMPOSITE_LAYER ); 01507 loops.reset(); 01508 for( i = loops.size();i--; ) 01509 { 01510 TopologyBridge* loop_bridge = loops.get_and_step(); 01511 CompositeLoop* comploop = new CompositeLoop(); 01512 compsurf->add( comploop ); 01513 if( loop_bridge->owner() ) 01514 { 01515 loop_bridge->owner()->swap_bridge( loop_bridge, comploop, false ); 01516 loop_bridge->owner(0); 01517 } 01518 //compsurf->hidden_entities().hide( loop_bridge ); 01519 01520 coedges.clean_out(); 01521 //loop_bridge->get_children_virt( coedges ); 01522 //fix_up_query_results(coedges); 01523 loop_bridge->get_children( coedges, false, COMPOSITE_LAYER ); 01524 01525 coedges.reset(); 01526 CompositeCoEdge* prev = 0; 01527 for( j = coedges.size(); j--; ) 01528 { 01529 CoEdgeSM* coedge = dynamic_cast<CoEdgeSM*>(coedges.get_and_step()); 01530 CompositeCoEdge* comp_coedge = dynamic_cast<CompositeCoEdge*>(coedge); 01531 if( !comp_coedge ) 01532 { 01533 curves.clean_out(); 01534 //coedge->get_children_virt( curves ); 01535 //fix_up_query_results(curves); 01536 coedge->get_children(curves, false, COMPOSITE_LAYER); 01537 assert( curves.size() == 1 ); 01538 replace_curve( dynamic_cast<Curve*>(curves.get()) ); 01539 comp_coedge = dynamic_cast<CompositeCoEdge*>(coedge->owner()); 01540 assert( comp_coedge!= NULL ); 01541 } 01542 else 01543 { 01544 /* 01545 PRINT_INFO("\nStart: %lf %lf %lf", comp_coedge->start_point()->coordinates().x(), 01546 comp_coedge->start_point()->coordinates().y(), comp_coedge->start_point()->coordinates().z()); 01547 PRINT_INFO("\nEnd: %lf %lf %lf", comp_coedge->end_point()->coordinates().x(), 01548 comp_coedge->end_point()->coordinates().y(), comp_coedge->end_point()->coordinates().z()); 01549 */ 01550 } 01551 comploop->insert_after( comp_coedge, prev ); 01552 prev = comp_coedge; 01553 } 01554 } 01555 01556 return compsurf; 01557 } 01558 01559 01560 01561 //------------------------------------------------------------------------- 01562 // Purpose : Replace a "real" lump with a composite 01563 // 01564 // Special Notes : 01565 // 01566 // Creator : Jason Kraftcheck 01567 // 01568 // Creation Date : 07/19/02 01569 //------------------------------------------------------------------------- 01570 CompositeLump* CompositeEngine::replace_lump( Lump* lump ) 01571 { 01572 DLIList<TopologyBridge*> shells, surfaces; 01573 int i, j; 01574 if( dynamic_cast<CompositeLump*>(lump) ) 01575 return 0; 01576 01577 CompositeLump* complump = new CompositeLump( lump ); 01578 //lump->get_children_virt( shells ); 01579 //fix_up_query_results(shells); 01580 lump->get_children(shells, false, COMPOSITE_LAYER); 01581 shells.reset(); 01582 for( i = shells.size();i--; ) 01583 { 01584 CompositeShell* compshell = new CompositeShell(); 01585 complump->add( compshell ); 01586 TopologyBridge* shell_bridge = shells.get_and_step(); 01587 if( shell_bridge->owner() ) 01588 { 01589 shell_bridge->owner()->swap_bridge(shell_bridge, compshell, false); 01590 shell_bridge->owner(0); 01591 } 01592 //complump->hidden_entities().hide( shell_bridge ); 01593 01594 01595 surfaces.clean_out(); 01596 //shell_bridge->get_children_virt( surfaces ); 01597 //fix_up_query_results(surfaces); 01598 shell_bridge->get_children(surfaces, false, COMPOSITE_LAYER); 01599 01600 surfaces.reset(); 01601 for( j = surfaces.size(); j--; ) 01602 { 01603 Surface* surface = dynamic_cast<Surface*>(surfaces.get_and_step()); 01604 CompositeSurface* compsurf = dynamic_cast<CompositeSurface*>(surface); 01605 if( !compsurf ) 01606 { 01607 compsurf = replace_surface( surface ); 01608 assert( compsurf!= NULL ); 01609 } 01610 01611 compshell->add( compsurf, CUBIT_FORWARD ); 01612 } 01613 } 01614 01615 return complump; 01616 } 01617 01618 01619 01620 //------------------------------------------------------------------------- 01621 // Purpose : Replace a "real" bodysm with a composite 01622 // 01623 // Special Notes : 01624 // 01625 // Creator : Jason Kraftcheck 01626 // 01627 // Creation Date : 07/19/02 01628 //------------------------------------------------------------------------- 01629 CompositeBody* CompositeEngine::replace_body( BodySM* body ) 01630 { 01631 DLIList<TopologyBridge*> lumps; 01632 int i; 01633 if( dynamic_cast<CompositeBody*>(body) ) 01634 return 0; 01635 01636 CompositeBody* compbody = new CompositeBody( ); 01637 compbody->add(body); 01638 body->get_children( lumps, false, COMPOSITE_LAYER ); 01639 lumps.reset(); 01640 for( i = lumps.size();i--; ) 01641 { 01642 Lump* lump = dynamic_cast<Lump*>(lumps.get_and_step()); 01643 CompositeLump* complump = dynamic_cast<CompositeLump*>(lump); 01644 if( !complump ) 01645 complump = replace_lump( lump ); 01646 compbody->add( complump ); 01647 } 01648 01649 return compbody; 01650 } 01651 01652 TBPoint* CompositeEngine::remove_composite( CompositePoint* composite ) 01653 { 01654 assert( composite->next_curve() == 0 ); 01655 assert( !dynamic_cast<HiddenEntitySet*>(composite->owner()) ); 01656 TBPoint* result = composite->get_point(); 01657 delete composite; 01658 return result; 01659 } 01660 01661 01662 01663 //------------------------------------------------------------------------- 01664 // Purpose : Reomve a 1-curve composite 01665 // 01666 // Special Notes : Inverse of replace_curve(..) 01667 // 01668 // Creator : Jason Kraftcheck 01669 // 01670 // Creation Date : 03/13/02 01671 //------------------------------------------------------------------------- 01672 Curve* CompositeEngine::remove_composite( CompositeCurve* composite ) 01673 { 01674 assert( composite->num_curves() == 1 && 01675 !composite->has_parent_composite_surface() && 01676 !dynamic_cast<HiddenEntitySet*>(composite->owner()) && 01677 !composite->is_stitched() ); 01678 01679 CompositeCoEdge* coedge = 0; 01680 while( (coedge = composite->first_coedge()) ) 01681 { 01682 assert( !coedge->get_loop() && coedge->num_coedges() == 1 ); 01683 composite->remove( coedge ); 01684 CoEdgeSM* real_coedge = coedge->get_coedge(0); 01685 coedge->remove_coedge( 0 ); 01686 if( coedge->owner() ) 01687 coedge->owner()->swap_bridge( coedge, real_coedge, false ); 01688 delete coedge; 01689 } 01690 01691 CompositePoint* sp = composite->start_point(); 01692 CompositePoint* ep = composite->end_point(); 01693 Curve* curve = composite->get_curve( 0 ); 01694 bool reversed = composite->get_sense(0) == CUBIT_REVERSED; 01695 composite->remove_curve(0); 01696 if( composite->owner() ) 01697 composite->owner()->swap_bridge( composite, curve, reversed ); 01698 01699 composite->start_point(0); 01700 composite->end_point(0); 01701 delete composite; 01702 01703 if( ! sp->next_curve() ) 01704 remove_composite(sp); 01705 if( ep != sp && !ep->next_curve() ) 01706 remove_composite(ep); 01707 01708 // we must notify the graphics of the modify from "real" to virtual -- KGM 01709 // I realize that this is not where the other notifies are completed but there 01710 // is no knowledge of the change later on. 01711 CubitObservable* observable = dynamic_cast<CubitObservable*>(curve->topology_entity()); 01712 if (observable) 01713 { 01714 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, dynamic_cast<RefEntity*>(curve->topology_entity()))); 01715 } 01716 01717 return curve; 01718 } 01719 01720 01721 //------------------------------------------------------------------------- 01722 // Purpose : Remove a 1-surface composite 01723 // 01724 // Special Notes : inverse of replace_surface(..) 01725 // 01726 // Creator : Jason Kraftcheck 01727 // 01728 // Creation Date : 03/13/02 01729 //------------------------------------------------------------------------- 01730 Surface* CompositeEngine::remove_composite( CompositeSurface* composite ) 01731 { 01732 assert( ! composite->has_hidden_entities() ); 01733 assert( composite->next_co_surface(0) == 0 ); 01734 CompositeLoop* loop; 01735 CompositeCoEdge* coedge; 01736 CompositeCurve* curve; 01737 01738 while( (loop = composite->first_loop()) ) 01739 { 01740 composite->remove( loop ); 01741 while( (coedge = loop->first_coedge()) ) 01742 { 01743 loop->remove(coedge); 01744 curve = coedge->get_curve(); 01745 if( curve->num_curves() == 1 && 01746 !curve->has_parent_composite_surface() && 01747 !curve->is_stitched()) 01748 remove_composite(curve); 01749 } 01750 delete loop; 01751 } 01752 01753 Surface* surface = composite->get_surface( 0 ); 01754 bool reversed = composite->get_sense(0) == CUBIT_REVERSED; 01755 composite->remove_surface(0); 01756 if( composite->owner() ) 01757 composite->owner()->swap_bridge( composite, surface, reversed ); 01758 delete composite; 01759 01760 return surface; 01761 } 01762 01763 //------------------------------------------------------------------------- 01764 // Purpose : Remove a 1-lump composite 01765 // 01766 // Special Notes : inverse of replace_lump(..) 01767 // 01768 // Creator : Jason Kraftcheck 01769 // 01770 // Creation Date : 07/19/02 01771 //------------------------------------------------------------------------- 01772 Lump* CompositeEngine::remove_composite( CompositeLump* composite ) 01773 { 01774 assert( composite->num_lumps() == 1 ); 01775 assert( composite->get_body() == 0 ); 01776 01777 for( CompositeShell* shell = composite->first_shell(); 01778 shell != 0; 01779 shell = composite->next_shell( shell ) ) 01780 { 01781 composite->remove( shell ); 01782 while( shell->first_co_surf() ) 01783 { 01784 CompositeCoSurf* cos = shell->first_co_surf(); 01785 CompositeSurface* surface = cos->get_surface(); 01786 shell->remove( cos ); 01787 surface->remove( cos ); 01788 delete cos; 01789 01790 if( surface->next_co_surface() == 0 && 01791 !surface->has_hidden_entities() ) 01792 remove_composite( surface ); 01793 } 01794 delete shell; 01795 } 01796 01797 Lump* result = composite->get_lump( 0 ); 01798 composite->remove_bridge(result); 01799 if( composite->owner() ) 01800 composite->owner()->swap_bridge( composite, result, false ); 01801 delete composite; 01802 01803 return result; 01804 } 01805 01806 01807 //------------------------------------------------------------------------- 01808 // Purpose : Remove a 1-body composite 01809 // 01810 // Special Notes : inverse of replace_body(..) 01811 // 01812 // Creator : Jason Kraftcheck 01813 // 01814 // Creation Date : 07/19/02 01815 //------------------------------------------------------------------------- 01816 BodySM* CompositeEngine::remove_composite( CompositeBody* composite ) 01817 { 01818 assert( composite->num_bodies() == 1 ); 01819 01820 while( CompositeLump* lump = composite->next_lump() ) 01821 { 01822 composite->remove( lump ); 01823 remove_composite( lump ); 01824 } 01825 01826 BodySM* result = composite->get_body( 0 ); 01827 composite->remove_bridge(result); 01828 if( composite->owner() ) 01829 composite->owner()->swap_bridge( composite, result, false ); 01830 delete composite; 01831 01832 return result; 01833 } 01834 01835 01836 //------------------------------------------------------------------------- 01837 // Purpose : Combine two curves into a composite 01838 // 01839 // Special Notes : 01840 // 01841 // Creator : Jason Kraftcheck 01842 // 01843 // Creation Date : 03/13/02 01844 //------------------------------------------------------------------------- 01845 CompositeCurve* CompositeEngine::combine( CompositeCurve* keep, 01846 CompositeCurve* dead, 01847 CompositePoint* keep_point, 01848 bool remove_partitions ) 01849 { 01850 if( keep->start_point() == keep->end_point() || 01851 dead->start_point() == dead->end_point() ) 01852 return 0; 01853 01854 // find the point to remove by compositing. 01855 CompositePoint* common = keep->common_point( dead ); 01856 if (!common) 01857 return 0; 01858 01859 if (keep_point && common == keep_point) 01860 { 01861 common = keep->other_point(common); 01862 if (dead->other_point(common) != keep_point) 01863 return 0; 01864 } 01865 01866 bool prepend = (common == keep->start_point()); 01867 bool reverse = ((common == dead->end_point()) != prepend); 01868 01869 // Order coedges such that each coedge from the 01870 // dead curve is grouped with the corresponding 01871 // coedge from the curve to be kept. 01872 DLIList<CompositeCoEdge*> dead_coedges, sorted_coedges; 01873 CompositeCoEdge* coedge; 01874 for( coedge = dead->first_coedge(); 01875 coedge != 0; 01876 coedge = dead->next_coedge( coedge ) ) 01877 dead_coedges.append( coedge ); 01878 01879 int keep_count = 0; 01880 CompositeCoEdge *keep_coedge = NULL; 01881 for( keep_coedge = keep->first_coedge(); 01882 keep_coedge != 0; 01883 keep_coedge = keep->next_coedge( keep_coedge ) ) 01884 { 01885 keep_count++; 01886 LoopSM* keep_loop = keep_coedge->get_parent_loop(); 01887 CubitSense keep_sense = keep_coedge->sense(); 01888 01889 for( int j = dead_coedges.size(); j--; ) 01890 { 01891 CompositeCoEdge* dead_coedge = dead_coedges.step_and_get(); 01892 if( dead_coedge->get_parent_loop() == keep_loop && 01893 (reverse == (keep_sense != dead_coedge->sense()) ) ) 01894 { 01895 dead_coedges.extract(); 01896 sorted_coedges.append( dead_coedge ); 01897 break; 01898 } 01899 } 01900 } 01901 01902 // If not all coedges were paired up, can't proceed. 01903 if( sorted_coedges.size() != keep_count ) 01904 return 0; 01905 01906 // If dead is reversed wrt keep, reverse it such that 01907 // both curves have the same relative sense. 01908 if( reverse ) 01909 { 01910 dead->reverse(); 01911 for( coedge = dead->first_coedge(); 01912 coedge != 0; 01913 coedge = dead->next_coedge( coedge) ) 01914 coedge->reverse(); 01915 } 01916 01917 // Combine the CoEdges 01918 sorted_coedges.reset(); 01919 for ( keep_coedge = keep->first_coedge(); 01920 keep_coedge != 0; 01921 keep_coedge = keep->next_coedge( keep_coedge ) ) 01922 { 01923 CompositeCoEdge* dead_coedge = sorted_coedges.get_and_step(); 01924 keep_coedge->combine( dead_coedge, prepend ); 01925 01926 if ( dead_coedge->owner() ) 01927 dead_coedge->owner()->remove_bridge( dead_coedge ); 01928 delete dead_coedge; 01929 } 01930 01931 01932 // hide point 01933 keep->hidden_entities().hide( common ); 01934 01935 // combine curves 01936 keep->combine( dead, prepend ); 01937 if (prepend) 01938 keep->start_point( dead->other_point( common ) ); 01939 else 01940 keep->end_point( dead->other_point( common ) ); 01941 01942 if (dead->owner()) 01943 dead->owner()->remove_bridge(dead); 01944 dead->start_point(0); 01945 dead->end_point(0); 01946 delete dead; 01947 01948 if( remove_partitions ) 01949 remove_partition_point( common ); 01950 01951 return keep; 01952 } 01953 01954 01955 //------------------------------------------------------------------------- 01956 // Purpose : Restore hidden point 01957 // 01958 // Special Notes : May create point-curve if point is hidden by a surface. 01959 // 01960 // Creator : Jason Kraftcheck 01961 // 01962 // Creation Date : 02/27/04 01963 //------------------------------------------------------------------------- 01964 CubitStatus CompositeEngine::restore_point( TBPoint* point ) 01965 { 01966 HiddenEntitySet* set; 01967 01968 CompositePoint* comp = dynamic_cast<CompositePoint*>(point); 01969 if (!comp) 01970 comp = dynamic_cast<CompositePoint*>(point->owner()); 01971 if (!comp) 01972 return CUBIT_FAILURE; 01973 01974 set = dynamic_cast<HiddenEntitySet*>(comp->owner()); 01975 if (!set) 01976 return CUBIT_FAILURE; 01977 01978 if (dynamic_cast<CompositeCurve*>(set->owner())) 01979 { 01980 point = comp->get_point(); 01981 if (!restore_point_in_curve(comp)) 01982 return CUBIT_FAILURE; 01983 01984 // check if we still have a composite point 01985 // if this was the only point splitting the curve, 01986 // then the composite point will have been destroyed. 01987 comp = dynamic_cast<CompositePoint*>(point->owner()); 01988 if (!comp) 01989 return CUBIT_SUCCESS; 01990 01991 // If the point is no longer hidden, we're done. 01992 set = dynamic_cast<HiddenEntitySet*>(comp->owner()); 01993 if (!set) 01994 return CUBIT_SUCCESS; 01995 } 01996 01997 // Need to create point-curve? 01998 if (dynamic_cast<CompositeSurface*>(set->owner())) 01999 { 02000 if (!restore_point_in_surface(comp)) 02001 return CUBIT_FAILURE; 02002 02003 // If the point is no longer hidden, we're done. 02004 set = dynamic_cast<HiddenEntitySet*>(comp->owner()); 02005 if (!set) 02006 return CUBIT_SUCCESS; 02007 } 02008 02009 // Something went wrong. 02010 return CUBIT_FAILURE; 02011 } 02012 02013 02014 02015 //------------------------------------------------------------------------- 02016 // Purpose : Restore a point removed when a curve was composited 02017 // (split a composite point) 02018 // 02019 // Special Notes : 02020 // 02021 // Creator : Jason Kraftcheck 02022 // 02023 // Creation Date : 03/13/02 02024 //------------------------------------------------------------------------- 02025 CubitStatus CompositeEngine::restore_point_in_curve( TBPoint* point ) 02026 { 02027 // find CompositePoint 02028 CompositePoint* comppoint = dynamic_cast<CompositePoint*>(point); 02029 if( !comppoint ) 02030 comppoint = dynamic_cast<CompositePoint*>(point->owner()); 02031 if( !comppoint ) 02032 return CUBIT_FAILURE; 02033 02034 // find CompositeCurve. 02035 HiddenEntitySet* hs = dynamic_cast<HiddenEntitySet*>(comppoint->owner()); 02036 if( !hs ) 02037 return CUBIT_FAILURE; 02038 CompositeCurve* compcurve = dynamic_cast<CompositeCurve*>(hs->owner()); 02039 if( !compcurve ) 02040 return CUBIT_FAILURE; 02041 02042 // find which curves in the composite contain the point 02043 DLIList<TopologyBridge*> points; 02044 int index = -1; 02045 for( int i = 0; i < compcurve->num_curves() && index < 0; i++ ) 02046 { 02047 Curve* curve = compcurve->get_curve(i); 02048 points.clean_out(); 02049 curve->get_children( points, true, COMPOSITE_LAYER ); 02050 for( int j = points.size(); j--; ) 02051 { 02052 TBPoint* pt = dynamic_cast<TBPoint*>(points.get_and_step()); 02053 assert( pt!= NULL ); 02054 if( pt == comppoint ) 02055 { 02056 index = i; 02057 break; 02058 } 02059 } 02060 } 02061 02062 assert( index >= 0 ); 02063 Curve *curve1, *curve2; 02064 return split( compcurve, index, curve1, curve2 ); 02065 } 02066 02067 02068 02069 02070 02071 02072 //------------------------------------------------------------------------- 02073 // Purpose : Split a composite at the index-th point (after the 02074 // index-th underlying curve) 02075 // 02076 // Special Notes : 02077 // 02078 // Creator : Jason Kraftcheck 02079 // 02080 // Creation Date : 03/13/02 02081 //------------------------------------------------------------------------- 02082 CubitStatus CompositeEngine::split( CompositeCurve* curve, int index, 02083 Curve*& result1, Curve*& result2 ) 02084 { 02085 result1 = result2 = 0; 02086 02087 // Split the composite geometry 02088 CompositeCurve* new_curve = curve->split( curve->get_curve(index) ); 02089 if( !new_curve ) 02090 return CUBIT_FAILURE; 02091 HiddenEntitySet* ownerSet = dynamic_cast<HiddenEntitySet*>(curve->owner()); 02092 if( ownerSet ) 02093 ownerSet->hide(new_curve); 02094 02095 // Split owning CoEdges 02096 for( CompositeCoEdge* old_coe = curve->first_coedge(); 02097 old_coe != 0; 02098 old_coe = curve->next_coedge( old_coe ) ) 02099 { 02100 CompositeCoEdge* new_coe = old_coe->split( index ); 02101 assert( new_coe != NULL ); 02102 new_curve->add( new_coe ); 02103 if( ownerSet ) 02104 ownerSet->hide(new_coe); 02105 02106 if( old_coe->get_loop() ) 02107 old_coe->get_loop()->insert_after( new_coe, old_coe ); 02108 } 02109 02110 // update end point of original curve 02111 DLIList<TopologyBridge*> children; 02112 int last = curve->num_curves() - 1; 02113 Curve* last_curve = curve->get_curve(last); 02114 children.clean_out(); 02115 last_curve->get_children( children, true, COMPOSITE_LAYER ); 02116 assert( children.size() == 2 ); 02117 children.reset(); 02118 if( curve->get_sense(last) == CUBIT_FORWARD ) 02119 children.step(); 02120 CompositePoint* endpt = dynamic_cast<CompositePoint*>(children.get()); 02121 assert( !!endpt ); 02122 CompositePoint* oldendpt = curve->end_point(); 02123 curve->end_point( endpt ); 02124 02125 // attach start and end point to new curve 02126 children.clean_out(); 02127 Curve* first_curve = new_curve->get_curve(0); 02128 first_curve->get_children( children, true, COMPOSITE_LAYER ); 02129 assert( children.size() == 2 ); 02130 children.reset(); 02131 if( new_curve->get_sense(0) == CUBIT_REVERSED ) 02132 children.step(); 02133 CompositePoint* startpt = dynamic_cast<CompositePoint*>(children.get()); 02134 assert( startpt!= NULL ); 02135 new_curve->start_point( startpt ); 02136 new_curve->end_point( oldendpt ); 02137 02138 // unhide restored (split) point 02139 HiddenEntitySet& old_hidden = curve->hidden_entities(); 02140 old_hidden.restore( curve->end_point() ); 02141 old_hidden.restore( new_curve->start_point() ); 02142 if( ownerSet ) 02143 { 02144 ownerSet->hide(curve->end_point()); 02145 if(new_curve->start_point() != curve->end_point() ) 02146 ownerSet->hide(new_curve->start_point()); 02147 } 02148 02149 // move other hidden points from old curve to new curve 02150 // as needed 02151 for( int j = 0; j < new_curve->num_curves(); j++ ) 02152 { 02153 Curve* r_curve = new_curve->get_curve(j); 02154 children.clean_out(); 02155 r_curve->get_children( children, true, COMPOSITE_LAYER ); 02156 TBPoint* sp = dynamic_cast<TBPoint*>(children.get_and_step() ); 02157 TBPoint* ep = dynamic_cast<TBPoint*>(children.get_and_step() ); 02158 assert( sp && ep && sp != ep ); 02159 if( old_hidden.restore( sp ) ) 02160 new_curve->hidden_entities().hide( sp ); 02161 if( old_hidden.restore( ep ) ) 02162 new_curve->hidden_entities().hide( ep ); 02163 } 02164 02165 // Remove composite geometry if a 'composite' of one curve 02166 result1 = curve; 02167 result2 = new_curve; 02168 if( curve->num_curves() == 1 && !ownerSet && 02169 !curve->has_parent_composite_surface() ) 02170 result1 = remove_composite( curve ); 02171 if( new_curve->num_curves() == 1 && !ownerSet && 02172 !new_curve->has_parent_composite_surface() ) 02173 result2 = remove_composite( new_curve ); 02174 02175 return CUBIT_SUCCESS; 02176 } 02177 02178 02179 //------------------------------------------------------------------------- 02180 // Purpose : Create a composite surface by removing a curve 02181 // 02182 // Special Notes : 02183 // 02184 // Creator : Jason Kraftcheck 02185 // 02186 // Creation Date : 03/13/02 02187 //------------------------------------------------------------------------- 02188 CompositeSurface* CompositeEngine::remove_curve( Curve* dead_curve, 02189 bool remove_partitions, 02190 Surface* survivor ) 02191 { 02192 DLIList<TopologyBridge*> temp, coedges, loops, surfaces, curves, 02193 surf1_shells, surf2_shells; 02194 02195 if( dynamic_cast<CompositeCurve*>(dead_curve->owner()) ) 02196 dead_curve = dynamic_cast<Curve*>(dead_curve->owner()); 02197 02198 // If this is a null-geometry composite curve (a composite 02199 // point-curve without a corresponding real point-curve), 02200 // just destroy it and hide the defining point. 02201 CompositeCurve* compcurve = dynamic_cast<CompositeCurve*>(dead_curve); 02202 if (compcurve && compcurve->num_curves() == 0) 02203 { 02204 CompositeSurface* surf = compcurve->first_coedge()->get_loop()->get_surface(); 02205 CompositePoint* geom_pt = destroy_point_curve(compcurve); 02206 surf->hidden_entities().hide(geom_pt); 02207 return surf; 02208 } 02209 02210 // Get two coedges to remove, and put curve(s) in 'curves' 02211 dead_curve->get_parents_virt( coedges ); 02212 if( coedges.size() != 2 ) 02213 return 0; 02214 02215 coedges.reset(); 02216 TopologyBridge* coedge1 = coedges.get_and_step(); 02217 TopologyBridge* coedge2 = coedges.get_and_step(); 02218 02219 // Get surfaces corresponding to loops 02220 loops.clean_out(); 02221 coedge1->get_parents_virt( loops ); 02222 assert( loops.size() == 1 ); 02223 surfaces.clean_out(); 02224 loops.get()->get_parents_virt( surfaces ); 02225 assert( surfaces.size() == 1 ); 02226 Surface* surface1 = dynamic_cast<Surface*>(surfaces.get()); 02227 02228 loops.clean_out(); 02229 coedge2->get_parents_virt( loops ); 02230 assert( loops.size() == 1 ); 02231 surfaces.clean_out(); 02232 loops.get()->get_parents_virt( surfaces ); 02233 assert( surfaces.size() == 1 ); 02234 Surface* surface2 = dynamic_cast<Surface*>(surfaces.get()); 02235 02236 if (surface2 == survivor) 02237 std::swap(surface1,surface2); 02238 02239 // Make sure surfaces have same parent shells 02240 surface1->get_parents_virt( surf1_shells ); 02241 surface2->get_parents_virt( surf2_shells ); 02242 if( surf1_shells != surf2_shells ) 02243 return 0; 02244 02245 // get/make composites of surfaces 02246 CompositeSurface* compsurf1 = dynamic_cast<CompositeSurface*>(surface1); 02247 if( ! compsurf1 ) 02248 { 02249 compsurf1 = replace_surface( surface1 ); 02250 } 02251 02252 CompositeSurface* compsurf2 = 0; 02253 if( surface2 == surface1 ) 02254 { 02255 compsurf2 = compsurf1; 02256 } 02257 else 02258 { 02259 compsurf2 = dynamic_cast<CompositeSurface*>(surface2); 02260 if( !compsurf2 ) 02261 { 02262 compsurf2 = replace_surface( surface2 ); 02263 } 02264 } 02265 assert( compsurf1 && compsurf2 ); 02266 02267 // get composite(s) of curve(s) 02268 compcurve = dynamic_cast<CompositeCurve*>(dead_curve); 02269 if( !compcurve) 02270 compcurve = dynamic_cast<CompositeCurve*>(dead_curve->owner()); 02271 assert( !!compcurve ); 02272 02273 // Get composite coedges 02274 CompositeCoEdge *compcoedge1 = dynamic_cast<CompositeCoEdge*>(coedge1); 02275 if (!compcoedge1) 02276 compcoedge1 = dynamic_cast<CompositeCoEdge*>(coedge1->owner()); 02277 CompositeCoEdge *compcoedge2 = dynamic_cast<CompositeCoEdge*>(coedge2); 02278 if (!compcoedge2) 02279 compcoedge2 = dynamic_cast<CompositeCoEdge*>(coedge2->owner()); 02280 02281 // combine the composite surfaces (not loops yet.) 02282 if( compsurf1 != compsurf2 ) 02283 { 02284 // If second surface has opposite sense, fix it so 02285 // that both have the same sense. 02286 if( compcoedge2->sense() == compcoedge1->sense() ) 02287 { 02288 bool b_reverse_coedges = true; // automatically handle reversing the coedges for the loop 02289 compsurf2->reverse_sense(); 02290 for( CompositeLoop* loop = compsurf2->first_loop(); 02291 loop != 0; 02292 loop = compsurf2->next_loop( loop ) ) 02293 loop->reverse(b_reverse_coedges); 02294 } 02295 02296 // Move all loops from old surface to new 02297 while( CompositeLoop* loop = compsurf2->first_loop() ) 02298 { 02299 compsurf2->remove( loop ); 02300 compsurf1->add( loop ); 02301 } 02302 02303 // Combine the set of underlying, real surfaces 02304 compsurf1->combine( compsurf2 ); 02305 if( compsurf2->owner() ) 02306 compsurf2->owner()->remove_bridge( compsurf2 ); 02307 delete compsurf2; 02308 compsurf2 = 0; 02309 } 02310 02311 CompositeLoop* loop1 = compcoedge1->get_loop(); 02312 CompositeLoop* loop2 = compcoedge2->get_loop(); 02313 02314 bool split_loop = false; 02315 02316 // same loop => remove sipe || split loop 02317 if( loop1 == loop2 ) 02318 { 02319 // split loop 02320 if( loop1->next_coedge( compcoedge1 ) != compcoedge2 && 02321 loop1->prev_coedge( compcoedge1 ) != compcoedge2 ) 02322 { 02323 split_loop = true; 02324 loop2 = new CompositeLoop(); 02325 CompositeCoEdge* coedge = loop1->next_coedge( compcoedge1 ); 02326 CompositeCoEdge* prev = 0; 02327 while( coedge != compcoedge2 ) 02328 { 02329 loop1->remove( coedge ); 02330 loop2->insert_after( coedge, prev ); 02331 prev = coedge; 02332 coedge = loop1->next_coedge( compcoedge1 ); 02333 } 02334 compsurf1->add( loop2 ); 02335 } 02336 02337 loop1->remove( compcoedge1 ); 02338 loop1->remove( compcoedge2 ); 02339 02340 //if we have a merged surface, when we split the loop into two loops, 02341 //we can end up with the original two loops in the same bridge manager 02342 02343 if( split_loop && loop1->bridge_manager() && loop1->bridge_manager()->number_of_bridges() == 2 ) 02344 { 02345 DLIList<TopologyBridge*> merged_loops; 02346 loop1->bridge_manager()->get_bridge_list( merged_loops ); 02347 LoopSM *loop1 = static_cast<LoopSM*>(merged_loops[0]); 02348 LoopSM *loop2 = static_cast<LoopSM*>(merged_loops[1]); 02349 DLIList<CoEdgeSM*> coedges1, coedges2; 02350 loop1->coedgesms( coedges1 ); 02351 loop2->coedgesms( coedges2 ); 02352 02353 if( coedges1.size() == coedges2.size() ) 02354 loop1->bridge_manager()->remove_bridge( merged_loops[1] ); 02355 } 02356 02357 if( loop1->num_coedges() == 0 ) 02358 { 02359 compsurf1->remove( loop1 ); 02360 delete loop1; 02361 } 02362 } 02363 // stitch loops 02364 else 02365 { 02366 CompositeCoEdge* coedge; 02367 02368 // insert coedges 02369 while( loop2->num_coedges() > 1 ) // all but the dead one 02370 { 02371 coedge = loop2->next_coedge( compcoedge2 ); 02372 loop2->remove( coedge ); 02373 loop1->insert_before( coedge, compcoedge1 ); 02374 } 02375 loop1->remove( compcoedge1 ); 02376 loop2->remove( compcoedge2 ); 02377 assert( loop2->num_coedges() == 0 ); 02378 if( loop2->get_surface() ) 02379 loop2->get_surface()->remove( loop2 ); 02380 delete loop2; 02381 02382 // If loops only had one coedge each, then we 02383 // just removed a hole. 02384 if( loop1->num_coedges() == 0 ) 02385 { 02386 if( loop1->get_surface() ) 02387 loop1->get_surface()->remove( loop1 ); 02388 delete loop1; 02389 } 02390 } 02391 02392 compsurf1->hidden_entities().hide( compcoedge1 ); 02393 compsurf1->hidden_entities().hide( compcoedge2 ); 02394 02395 // clean up dead curve(s) and points 02396 curves.clean_out(); 02397 compcurve->start_point()->get_parents_virt( curves ); 02398 if( curves.size() == 1 ) 02399 compsurf1->hidden_entities().hide( compcurve->start_point() ); 02400 curves.clean_out(); 02401 compcurve->end_point()->get_parents_virt( curves ); 02402 if( curves.size() == 1 ) 02403 compsurf1->hidden_entities().hide( compcurve->end_point() ); 02404 compsurf1->hidden_entities().hide( compcurve ); 02405 02406 if( remove_partitions ) 02407 remove_partition_curves( compcurve ); 02408 02409 return compsurf1; 02410 } 02411 02412 02413 static void cme_hide_surface( HiddenEntitySet& set, 02414 CompositeSurface* surface ) 02415 { 02416 set.hide( surface ); 02417 CompositeLoop* loop = 0; 02418 while (NULL != (loop = surface->next_loop( loop ))) 02419 { 02420 set.hide( loop ); 02421 CompositeCoEdge* coedge = loop->first_coedge(); 02422 do { 02423 set.hide( coedge ); 02424 02425 bool hide_curve = true; 02426 CompositeCurve* curve = coedge->get_curve(); 02427 CompositeCoEdge* curve_coedge = 0; 02428 while ((curve_coedge = curve->next_coedge( curve_coedge ))) 02429 if (curve_coedge->owner() != &set) 02430 { hide_curve = false; break; } 02431 02432 if (hide_curve) 02433 { 02434 set.hide( curve ); 02435 int num_pts = 1 + (curve->start_point() == curve->end_point()); 02436 for (int i = 0; i < num_pts; i++) 02437 { 02438 CompositePoint* pnt = i ? curve->end_point() : curve->start_point(); 02439 bool hide_pnt = true; 02440 CompositeCurve* pnt_curve = 0; 02441 while ((pnt_curve = pnt->next_curve( pnt_curve ))) 02442 if (pnt_curve->owner() != &set) 02443 { hide_pnt = false; break; } 02444 02445 if (hide_pnt) 02446 set.hide( pnt ); 02447 } 02448 } 02449 } while((coedge = loop->next_coedge(coedge)) != loop->first_coedge()); 02450 } 02451 } 02452 02453 static void cme_unhide_surface( CompositeSurface* surf ) 02454 { 02455 HiddenEntitySet* set = dynamic_cast<HiddenEntitySet*>(surf->owner()); 02456 assert( !!set ); 02457 set->restore( surf ); 02458 CompositeLoop* loop = 0; 02459 while (NULL != (loop = surf->next_loop( loop ))) 02460 { 02461 set->restore( loop ); 02462 CompositeCoEdge* coedge = loop->first_coedge(); 02463 do { 02464 if (coedge->owner() == set) 02465 { 02466 CompositeCurve* curve = coedge->get_curve(); 02467 set->restore( coedge ); 02468 set->restore( curve ); 02469 if (curve->start_point()->owner() == set) 02470 set->restore( curve->start_point() ); 02471 if (curve->end_point()->owner() == set) 02472 set->restore( curve->end_point() ); 02473 } 02474 } while ((coedge = loop->next_coedge(coedge)) != loop->first_coedge()); 02475 } 02476 } 02477 02478 02479 02480 //------------------------------------------------------------------------- 02481 // Purpose : Create composite volume by removing a surface 02482 // 02483 // Special Notes : 02484 // 02485 // Creator : Jason Kraftcheck 02486 // 02487 // Creation Date : 06/10/04 02488 //------------------------------------------------------------------------- 02489 CompositeLump* CompositeEngine::remove_surface( Surface* dead_surf, 02490 Surface* stitch_partner, 02491 bool /*remove_partitions*/ ) 02492 { 02493 bool okay = true; 02494 Surface* sptr; 02495 if ((sptr = dynamic_cast<Surface*>(dead_surf->owner()))) 02496 dead_surf = sptr; 02497 if ((sptr = dynamic_cast<Surface*>(stitch_partner->owner()))) 02498 stitch_partner = sptr; 02499 02500 // Get composite surfaces 02501 bool replaced_1 = false, replaced_2 = false; 02502 CompositeSurface *surf1 = 0, *surf2 = 0; 02503 if (NULL == (surf1 = dynamic_cast<CompositeSurface*>(dead_surf))) 02504 { 02505 surf1 = replace_surface( dead_surf ); 02506 replaced_1 = true; 02507 } 02508 if (NULL == stitch_partner) 02509 { 02510 surf2 = surf1; 02511 } 02512 else if (NULL == (surf2 = dynamic_cast<CompositeSurface*>(stitch_partner))) 02513 { 02514 surf2 = replace_surface( stitch_partner ); 02515 replaced_2 = true; 02516 } 02517 02518 // Check if surfaces are stitched 02519 if (surf2 != surf1) 02520 { 02521 std::set<CompositeLoop*> used_loops; 02522 CompositeLoop* loop = 0; 02523 while (NULL != (loop = surf1->next_loop(loop))) 02524 { 02525 CompositeCoEdge* coedge1 = loop->first_coedge(); 02526 CompositeCurve* curve = coedge1->get_curve(); 02527 CompositeCoEdge* coedge2 = 0; 02528 while (NULL != (coedge2 = curve->next_coedge(coedge2))) 02529 if (coedge2->get_loop() && 02530 coedge2->get_loop()->get_surface() == surf2) 02531 break; 02532 02533 if (!coedge2) 02534 { 02535 break; 02536 okay = false; 02537 } 02538 02539 CompositeLoop* loop2 = coedge2->get_loop(); 02540 if (used_loops.insert( loop2 ).second == false) 02541 { 02542 okay = false; 02543 break; 02544 } 02545 02546 CompositeCoEdge* coedge = coedge1; 02547 while ((coedge = loop->next_coedge(coedge)) != coedge1) 02548 { 02549 curve = coedge->get_curve(); 02550 coedge2 = 0; 02551 while (NULL != (coedge2 = curve->next_coedge(coedge2))) 02552 if (coedge2->get_loop() == loop2) 02553 break; 02554 02555 if (!coedge2) 02556 { 02557 okay = false; 02558 break; 02559 } 02560 } 02561 } 02562 surf1->stitch( surf2 ); 02563 02564 if (!okay) 02565 { 02566 if (replaced_1) 02567 remove_composite( surf1 ); 02568 if (replaced_2) 02569 remove_composite( surf2 ); 02570 return 0; 02571 } 02572 } 02573 02574 // Replace volumes/bodies with composites, combine bodies if necessary 02575 DLIList<BodySM*> body_list; 02576 surf1->bodysms( body_list ); 02577 if (body_list.size() != 1) 02578 return 0; 02579 02580 BodySM* body1 = body_list.pop(); 02581 BodySM* body2 = 0; 02582 CompositeBody* body = 0; 02583 02584 if (surf2) 02585 { 02586 surf2->bodysms( body_list ); 02587 if (body_list.size() != 1) 02588 return 0; 02589 body2 = body_list.pop(); 02590 } 02591 02592 if (body2 && body2 != body1) 02593 { 02594 body = combine_bodies( body1, body2 ); 02595 } 02596 else 02597 { 02598 if (NULL == (body = dynamic_cast<CompositeBody*>(body1)) && 02599 NULL == (body = dynamic_cast<CompositeBody*>(body1->owner()))) 02600 { 02601 body = replace_body( body1 ); 02602 } 02603 } 02604 02605 if (!body) 02606 return 0; 02607 02608 // Get CoSurfaces to combine must be exactly two of them. 02609 CompositeCoSurf *cosurf1 = 0, *cosurf2 = 0; 02610 cosurf1 = surf1->next_co_surface(NULL); 02611 cosurf2 = surf1->next_co_surface(cosurf1); 02612 if (!cosurf1) 02613 { 02614 okay = false; 02615 } 02616 else if (cosurf2) 02617 { 02618 if (surf2 || surf1->next_co_surface(cosurf2)) 02619 okay = false; 02620 } 02621 else if (surf2) 02622 { 02623 cosurf2 = surf2->next_co_surface(NULL); 02624 if (!cosurf2 || surf2->next_co_surface(cosurf2)) 02625 okay = false; 02626 } 02627 if (!okay) 02628 { 02629 // if (replaced_body) 02630 // restore_body( body ); 02631 return 0; 02632 } 02633 02634 02635 // combine the composite lumps (not shells yet.) 02636 CompositeLump* lump1 = cosurf1->get_shell()->get_lump(); 02637 CompositeLump* lump2 = cosurf2->get_shell()->get_lump(); 02638 if( lump1 != lump2 ) 02639 { 02640 02641 // Move all shells from old lump to new 02642 while( CompositeShell* shell = lump2->first_shell() ) 02643 { 02644 lump2->remove( shell ); 02645 lump1->add( shell ); 02646 } 02647 02648 // Combine the set of underlying, real lumps 02649 lump1->combine( lump2 ); 02650 if( lump2->owner() ) 02651 lump2->owner()->remove_bridge( lump2 ); 02652 body->remove(lump2); 02653 delete lump2; 02654 lump2 = 0; 02655 } 02656 02657 // remove surface(s) 02658 CompositeShell* shell1 = cosurf1->get_shell(); 02659 CompositeShell* shell2 = cosurf2->get_shell(); 02660 cme_hide_surface( lump1->hidden_entities(), surf1 ); 02661 if (surf2) 02662 cme_hide_surface( lump1->hidden_entities(), surf2 ); 02663 delete cosurf1; 02664 delete cosurf2; 02665 02666 if (shell1 != shell2) 02667 { 02668 while (CompositeCoSurf* cosurf = shell2->next_co_surf(0)) 02669 { 02670 shell2->remove( cosurf ); 02671 shell1->add( cosurf ); 02672 } 02673 lump1->remove( shell2 ); 02674 delete shell2; 02675 } 02676 else // if (shell1 == shell2) 02677 { 02678 shell2 = split_shell( shell1 ); 02679 if (shell2) 02680 lump1->add( shell2 ); 02681 } 02682 02683 return lump1; 02684 } 02685 02686 02687 //------------------------------------------------------------------------- 02688 // Purpose : Test if a CompositeShell needs to be split, and 02689 // split it 02690 // 02691 // Special Notes : Copied from PartitionEngine::split_shell 02692 // 02693 // Creator : Jason Kraftcheck 02694 // 02695 // Creation Date : 06/11/04 02696 //------------------------------------------------------------------------- 02697 CompositeShell* CompositeEngine::split_shell( CompositeShell* shell_to_split ) 02698 { 02699 std::map<CompositeSurface*, int> marks; 02700 02701 // Make sure all cosurface surface marks are cleared 02702 CompositeCoSurf* cosurf = 0; 02703 while( (cosurf = shell_to_split->next_co_surf( cosurf )) ) 02704 marks[cosurf->get_surface()] = 0; 02705 02706 // Identify non-manifold surfaces, marking them either 02707 // with a 2 if they can be used to split the volume 02708 // (if they are part of a connected patch for which the 02709 // bounadary of that patch intersects the volume boundary 02710 // at all curves) or a 3 if they are other non-manifold 02711 // surfaces. This will get a bit tricky if there are 02712 // non-manifold surfaces hanging off of the patch of 02713 // split surfaces. 02714 02715 // First for all non-manifold surfaces, if the surface has 02716 // a curve that is not shared with any other surface, mark 02717 // it with a 3. Otherwise mark it with a 2. 02718 cosurf = 0; 02719 DLIList<CompositeSurface*> surf_stack; 02720 while ( (cosurf = shell_to_split->next_co_surf(cosurf)) ) 02721 { 02722 CompositeSurface* surf = cosurf->get_surface(); 02723 // If we haven't done this surface yet and it is non-manifold 02724 if ( !marks[surf] && surf->find_next(cosurf) ) 02725 { 02726 marks[surf] = 2; 02727 bool no_free_curve = true; 02728 CompositeLoop* loop = 0; 02729 while( no_free_curve && (loop = surf->next_loop(loop)) ) 02730 { 02731 CompositeCoEdge* coedge = loop->first_coedge(); 02732 do 02733 { 02734 CompositeCurve* curve = coedge->get_curve(); 02735 // If the curve has more than one coedge, it 02736 // is not a free curve (this also accounts for 02737 // the case where the curve is a non-manifold 02738 // curve on the surface interioir -- e.g. a sipe) 02739 if ( !curve->next_coedge(coedge) && 02740 curve->next_coedge(0) == coedge ) 02741 { 02742 no_free_curve = false; 02743 break; 02744 } 02745 coedge = loop->next_coedge(coedge); 02746 } while( coedge != loop->first_coedge() ); 02747 } 02748 02749 if( !no_free_curve ) 02750 { 02751 marks[surf] = 3; 02752 surf_stack.append( surf ); 02753 } 02754 } 02755 } 02756 02757 // Now for each surface we marked with a three, traverse 02758 // and mark adjacent surfaces until we come to a curve 02759 // connected to more that two surfaces. 02760 while( surf_stack.size() ) 02761 { 02762 CompositeSurface* surf = surf_stack.pop(); 02763 CompositeLoop* loop = 0; 02764 while ( (loop = surf->next_loop(loop)) ) 02765 { 02766 CompositeCoEdge* coedge = loop->first_coedge(); 02767 do 02768 { 02769 CompositeCurve* curve = coedge->get_curve(); 02770 int split_count = 0; 02771 int boundary_count = 0; 02772 CompositeCoEdge* curve_coe = 0; 02773 while ( (curve_coe = curve->next_coedge(curve_coe) ) != NULL ) 02774 { 02775 CompositeSurface* curve_surf = curve_coe->get_loop()->get_surface(); 02776 switch ( marks[curve_surf] ) 02777 { 02778 case 0: boundary_count++; break; 02779 case 2: split_count++; break; 02780 } 02781 } 02782 02783 if ( split_count == 1 && !boundary_count ) 02784 { 02785 curve_coe = 0; 02786 while ( (curve_coe = curve->next_coedge(curve_coe) ) != NULL ) 02787 { 02788 CompositeSurface* curve_surf = curve_coe->get_loop()->get_surface(); 02789 if ( marks[curve_surf] == 2 ) 02790 { 02791 marks[curve_surf] = 3; 02792 surf_stack.append(curve_surf); 02793 } 02794 } 02795 } 02796 02797 coedge = loop->next_coedge( coedge ); 02798 } while( coedge != loop->first_coedge() ); 02799 } 02800 } 02801 02802 // Now build a new shell by traversing cofaces, marking 02803 // each with that will go in a new shell with a 1. 02804 02805 // Start with any cosurf that does not have a free 02806 // non-manifold surface (marked with a 3). We'll handle 02807 // free non-manifold surfaces later. 02808 std::set<CompositeCoSurf*> marked_cosurfs; 02809 DLIList<CompositeCoSurf*> cosurf_stack; 02810 cosurf = 0; 02811 while ( (cosurf = shell_to_split->next_co_surf(cosurf)) ) 02812 if ( marks[cosurf->get_surface()] != 3 ) 02813 break; 02814 if ( cosurf ) 02815 { 02816 marked_cosurfs.insert(cosurf); 02817 cosurf_stack.append( cosurf ); 02818 } 02819 02820 // Traverse over adjacent cosurfaces, marking them with a 1 02821 while (cosurf_stack.size()) 02822 { 02823 cosurf = cosurf_stack.pop(); 02824 CompositeSurface* surf = cosurf->get_surface(); 02825 CompositeLoop* loop = 0; 02826 while ( (loop = surf->next_loop(loop)) ) 02827 { 02828 CompositeCoEdge* coedge = loop->first_coedge(); 02829 do 02830 { 02831 CompositeCurve* curve = coedge->get_curve(); 02832 CompositeCoEdge* curve_coe = 0; 02833 CompositeCoSurf *boundary_cosurf = 0, *split_cosurf = 0; 02834 int split_cosurf_count = 0; 02835 while ( (curve_coe = curve->next_coedge(curve_coe)) ) 02836 { 02837 if ( curve_coe == coedge ) 02838 continue; 02839 02840 bool same_coe_sense = curve_coe->sense() == coedge->sense(); 02841 CompositeSurface* curve_surf = curve_coe->get_loop()->get_surface(); 02842 CompositeCoSurf* curve_cosurf = 0; 02843 while ( (curve_cosurf = curve_surf->next_co_surface(curve_cosurf)) ) 02844 { 02845 if ( curve_cosurf->get_shell() != shell_to_split ) 02846 continue; 02847 02848 bool same_cos_sense = curve_cosurf->sense() == cosurf->sense(); 02849 if ( same_cos_sense == same_coe_sense ) 02850 continue; 02851 02852 // Always choose split surface first if we 02853 // found one 02854 if ( marks[curve_cosurf->get_surface()] == 2 ) { 02855 split_cosurf_count++; 02856 split_cosurf = curve_cosurf; 02857 } 02858 02859 // Skip other non-manifold surfaces. We'll 02860 // handle those later. 02861 else if( marks[curve_cosurf->get_surface()] != 3 ) 02862 boundary_cosurf = curve_cosurf; 02863 } 02864 } 02865 02866 CompositeCoSurf* next_cosurf = split_cosurf ? split_cosurf : boundary_cosurf; 02867 if ( marked_cosurfs.find(next_cosurf) == marked_cosurfs.end() 02868 && split_cosurf_count < 2 ) 02869 { 02870 marked_cosurfs.insert(next_cosurf); 02871 cosurf_stack.append(next_cosurf); 02872 } 02873 02874 coedge = loop->next_coedge(coedge); 02875 } while( coedge != loop->first_coedge() ); 02876 } // end while (loop) 02877 } // end while (cosurf_stack.size()) 02878 02879 02880 // build lists of cosurfaces, one for each shell and 02881 // one of other non-manifold surfaces 02882 DLIList<CompositeCoSurf*> marked_list, unmarked_list, other_list; 02883 while( (cosurf = shell_to_split->next_co_surf(0)) ) 02884 { 02885 shell_to_split->remove(cosurf); 02886 if ( marks[cosurf->get_surface()] == 3 ) 02887 other_list.append( cosurf ); 02888 else if( marked_cosurfs.find(cosurf) != marked_cosurfs.end() ) 02889 marked_list.append( cosurf ); 02890 else 02891 unmarked_list.append( cosurf ); 02892 } 02893 02894 // If one of marked_list or unmarked_list is empty, 02895 // we can't split the shell yet. Put cofaces back in 02896 // shell and exit. 02897 if ( !marked_list.size() || !unmarked_list.size() ) 02898 { 02899 marked_list += unmarked_list; 02900 marked_list += other_list; 02901 marked_list.reverse(); 02902 while ( marked_list.size() ) 02903 { 02904 cosurf = marked_list.pop(); 02905 shell_to_split->add( cosurf ); 02906 } 02907 return 0; 02908 } 02909 02910 // Put unmarked list back in old shell 02911 unmarked_list.reverse(); 02912 while ( unmarked_list.size() ) 02913 { 02914 cosurf = unmarked_list.pop(); 02915 shell_to_split->add(cosurf); 02916 } 02917 02918 // Put marked list in new shell 02919 CompositeShell* new_shell = new CompositeShell; 02920 marked_list.reverse(); 02921 while ( marked_list.size() ) 02922 { 02923 cosurf = marked_list.pop(); 02924 new_shell->add(cosurf); 02925 } 02926 02927 // Now sort out other non-manifold surfaces 02928 02929 // Clear marks and get list of surface from cosurfaces 02930 surf_stack.clean_out(); 02931 while( other_list.size() ) 02932 { 02933 cosurf = other_list.pop(); 02934 CompositeSurface* surf = cosurf->get_surface(); 02935 if ( marks[surf] ) 02936 surf_stack.append(surf); 02937 } 02938 02939 insert_nonmanifold_surfaces( surf_stack, shell_to_split, new_shell ); 02940 return new_shell; 02941 } 02942 02943 //------------------------------------------------------------------------- 02944 // Purpose : After a shell is split, determine which of the two 02945 // resulting shells each non-manifold surface belongs in. 02946 // 02947 // Special Notes : Copied from PartitionEngine::insert_nonmanifold_surfaces 02948 // 02949 // Creator : Jason Kraftcheck 02950 // 02951 // Creation Date : 06/11/04 02952 //------------------------------------------------------------------------- 02953 void CompositeEngine::insert_nonmanifold_surfaces( 02954 DLIList<CompositeSurface*>& surf_stack, 02955 CompositeShell* shell1, 02956 CompositeShell* shell2 ) 02957 { 02958 DLIList<CompositeSurface*> known_list(surf_stack.size()), 02959 unknown_list(surf_stack.size()); 02960 02961 CompositeCoSurf* cosurf; 02962 CompositeSurface* surf; 02963 CompositeLoop* loop; 02964 CompositeCoEdge *coedge, *curve_coe; 02965 CompositeCurve* curve; 02966 02967 // Loop until we've placed all the surfaces in one 02968 // shell or the other. 02969 while ( surf_stack.size() ) 02970 { 02971 bool did_some = false; 02972 02973 // Put any surfaces for which we immediately 02974 // know the shell into the appropriate shell. 02975 // Put others in known_list or unknown_list 02976 // depending on if we can determine which shell 02977 // they go in using a geometric comparison. 02978 known_list.clean_out(); 02979 unknown_list.clean_out(); 02980 02981 // Take all surfaces out of stack in this loop. 02982 // We might put some back in after the loop (thus 02983 // the outer loop.) 02984 while ( surf_stack.size() ) 02985 { 02986 surf = surf_stack.pop(); 02987 02988 CompositeShell* known_shell = 0; 02989 bool found_shell = false; 02990 loop = 0; 02991 while ( (loop = surf->next_loop(loop)) ) 02992 { 02993 coedge = loop->first_coedge(); 02994 do 02995 { 02996 curve = coedge->get_curve(); 02997 curve_coe = 0; 02998 while ( (curve_coe = curve->next_coedge(curve_coe)) ) 02999 { 03000 CompositeSurface* surf = curve_coe->get_loop()->get_surface(); 03001 cosurf = 0; 03002 while ( (cosurf = surf->next_co_surface( cosurf )) ) 03003 { 03004 if( cosurf->get_shell() == shell1 || 03005 cosurf->get_shell() == shell2 ) 03006 { 03007 found_shell = true; 03008 if ( known_shell && known_shell != cosurf->get_shell() ) 03009 known_shell = 0; 03010 else 03011 known_shell = cosurf->get_shell(); 03012 } 03013 } 03014 } 03015 03016 coedge = loop->next_coedge(coedge); 03017 } while( coedge != loop->first_coedge() ); 03018 } // end while(loop) 03019 03020 // This surface does not intersect the shell at 03021 // any curve. We can't do this one yet. 03022 if ( !found_shell ) 03023 { 03024 unknown_list.append( surf ); 03025 continue; 03026 } 03027 03028 // This surface intersected both shells at some 03029 // curves, but did not have a curve that intersected 03030 // only one shell. We can do this one geometricly 03031 // if we have to. 03032 if ( !known_shell ) 03033 { 03034 known_list.append( surf ); 03035 continue; 03036 } 03037 03038 // If we got this far, then the surface had at least 03039 // one curve that intersected only one of the shells. 03040 // We know it goes in that shell. 03041 did_some = true; 03042 CompositeCoSurf* cosurf1 = surf->find_first((CompositeShell*)0); 03043 CompositeCoSurf* cosurf2 = surf->find_next(cosurf1); 03044 known_shell->add(cosurf1); 03045 known_shell->add(cosurf2); 03046 03047 } // while(surf_stack) -- the inside one 03048 03049 // Unknown_list always goes back in surf_stack to 03050 // try again. 03051 surf_stack += unknown_list; 03052 03053 // If we did some surfaces, then put the rest back 03054 // in surf_stack and try again. If they intersect 03055 // one of the surfaces we did place in this iteration, 03056 // we can avoid needing to do geometric checks. 03057 if ( did_some ) 03058 { 03059 surf_stack += known_list; 03060 continue; 03061 } 03062 03063 // If known_list is empty, somethings wrong (we're 03064 // going to loop forever.) Abort the loop and try 03065 // to recover as best we can. 03066 if( !known_list.size() ) 03067 break; 03068 03069 // choose a single surface in do a geometric comparison 03070 // for, and put the rest back in surf_stack 03071 surf = known_list.pop(); 03072 surf_stack += known_list; 03073 03074 bool in_shell = false; 03075 if ( ! inside_shell( shell2, surf, in_shell ) ) 03076 { 03077 // if inside_shell failed, abort. 03078 surf_stack.append(surf); 03079 break; 03080 } 03081 03082 CompositeShell* shell = in_shell ? shell2 : shell1; 03083 shell->add(surf->find_first((CompositeShell*)0)); 03084 shell->add(surf->find_first((CompositeShell*)0)); 03085 } 03086 03087 // something went wrong 03088 if( surf_stack.size() ) 03089 { 03090 PRINT_ERROR("Internal error splitting volume at %s:%d\n" 03091 "Topology may be invalid. Please report this.\n", 03092 __FILE__, __LINE__); 03093 while( surf_stack.size() ) 03094 { 03095 CompositeSurface* surf = surf_stack.pop(); 03096 cosurf = 0; 03097 while( (cosurf = surf->next_co_surface(cosurf)) ) 03098 if( !cosurf->get_shell() ) 03099 shell1->add(cosurf); 03100 } 03101 } 03102 } 03103 03104 03105 CubitStatus CompositeEngine::inside_shell( CompositeShell* const shell, 03106 CompositeSurface* const surf, 03107 bool& result ) 03108 { 03109 // Find the curve and coedge at which the nonmanifold surface 03110 // intersects the shells 03111 CompositeLoop* loop = 0; 03112 CompositeCoEdge *nonman_coedge = 0; 03113 while ( !nonman_coedge && (loop = surf->next_loop(loop)) ) 03114 { 03115 CompositeCoEdge* loop_coedge = loop->first_coedge(); 03116 do 03117 { 03118 // Check if this curve is the curve of intersection 03119 // Iterate through curve coedges. 03120 CompositeCurve* curve = loop_coedge->get_curve(); 03121 CompositeCoEdge* curve_coedge = 0; 03122 while ( (curve_coedge = curve->next_coedge(curve_coedge)) ) 03123 { 03124 03125 CompositeSurface* coedge_surf = curve_coedge->get_loop()->get_surface(); 03126 if( coedge_surf->find_first(shell) ) 03127 { 03128 nonman_coedge = curve_coedge; 03129 break; 03130 } 03131 } 03132 03133 loop_coedge = loop->next_coedge(loop_coedge); 03134 } while( !nonman_coedge && loop_coedge != loop->first_coedge() ); 03135 } 03136 03137 if ( !nonman_coedge ) // bad input! 03138 return CUBIT_FAILURE; 03139 03140 // There must exist two surfaces in the shell that are manifold 03141 // in the shell and that are adjacent to the curve 03142 CompositeCurve* common_curve = nonman_coedge->get_curve(); 03143 CompositeCoSurf *cosurf1 = 0, *cosurf2 = 0, *cosurf; 03144 CompositeCoEdge *coedge1 = 0, *coedge2 = 0, *coedge = 0; 03145 while ( (coedge = common_curve->next_coedge(coedge)) ) 03146 { 03147 CompositeSurface* surf = coedge->get_loop()->get_surface(); 03148 if ( (cosurf = surf->find_first(shell)) && !surf->find_next(cosurf) ) 03149 { 03150 if( coedge1 ) { 03151 coedge2 = coedge; 03152 cosurf2 = cosurf; 03153 } else { 03154 coedge1 = coedge; 03155 cosurf1 = cosurf; 03156 } 03157 } 03158 } 03159 if ( !coedge1 || !coedge2 ) 03160 return CUBIT_FAILURE; 03161 03162 // Evaluate normals at midpoint of curve 03163 CubitVector base, tangent, point; 03164 double u = (common_curve->start_param()+common_curve->end_param())/2.0; 03165 common_curve->position_from_u( u, base ); 03166 common_curve->closest_point( base, point, &tangent ); 03167 tangent.normalize(); 03168 03169 CubitVector normal1, normal2, normal; 03170 surf->closest_point( base, 0, &normal ); 03171 cosurf1->get_surface()->closest_point( base, 0, &normal1 ); 03172 cosurf2->get_surface()->closest_point( base, 0, &normal2 ); 03173 03174 // Try to handle tangencies 03175 bool fix1 = (normal1 * normal).length_squared() < CUBIT_RESABS; 03176 bool fix2 = (normal2 * normal).length_squared() < CUBIT_RESABS; 03177 if ( fix1 || fix2 ) 03178 { 03179 CubitVector dir = tangent * normal; 03180 double len = dir.length(); 03181 assert(len > GEOMETRY_RESABS); 03182 dir /= len; 03183 if ( nonman_coedge->sense() == CUBIT_FORWARD ) 03184 dir = -dir; 03185 03186 CubitVector diag = surf->bounding_box().diagonal(); 03187 if ( fix1 ) 03188 { 03189 CubitVector d = cosurf1->get_surface()->bounding_box().diagonal(); 03190 if ( diag.x() < d.x() ) diag.x(d.x()); 03191 if ( diag.y() < d.y() ) diag.y(d.y()); 03192 if ( diag.z() < d.z() ) diag.z(d.z()); 03193 } 03194 if( fix2 ) 03195 { 03196 CubitVector d = cosurf2->get_surface()->bounding_box().diagonal(); 03197 if ( diag.x() < d.x() ) diag.x(d.x()); 03198 if ( diag.y() < d.y() ) diag.y(d.y()); 03199 if ( diag.z() < d.z() ) diag.z(d.z()); 03200 } 03201 03202 double step = 1e-3 * fabs( diag % dir ); 03203 if ( step < 2*GEOMETRY_RESABS ) 03204 step = 2*GEOMETRY_RESABS; 03205 03206 for ( int i = 0; i < 1000; i++ ) 03207 { 03208 point = base + i * step * dir; 03209 surf->closest_point( base, 0, &normal ); 03210 if( fix1 ) 03211 cosurf1->get_surface()->closest_point( base, 0, &normal1 ); 03212 if( fix2 ) 03213 cosurf2->get_surface()->closest_point( base, 0, &normal2 ); 03214 03215 bool done1 = !fix1 || (normal1 * normal).length_squared() > CUBIT_RESABS; 03216 bool done2 = !fix2 || (normal2 * normal).length_squared() > CUBIT_RESABS; 03217 if ( done1 && done2 ) 03218 { 03219 fix1 = fix2 = false; 03220 break; 03221 } 03222 } 03223 } 03224 03225 if ( fix1 || fix2 ) 03226 { 03227 PRINT_ERROR("Failed to adjust for surface tangencies.\n" 03228 "This is a BUG. %s:%d\n", __FILE__, __LINE__ ); 03229 return CUBIT_FAILURE; 03230 } 03231 03232 if ( nonman_coedge->sense() == CUBIT_FORWARD ) 03233 normal = -normal; 03234 if ( cosurf1->sense() == coedge1->sense() ) 03235 normal1 = -normal1; 03236 if ( cosurf2->sense() == coedge2->sense() ) 03237 normal2 = -normal2; 03238 03239 result = tangent.vector_angle(normal1, normal ) <= 03240 tangent.vector_angle(normal1, normal2); 03241 return CUBIT_SUCCESS; 03242 } 03243 03244 03245 03246 03247 03248 //------------------------------------------------------------------------- 03249 // Purpose : Destroy a point-curve 03250 // 03251 // Special Notes : 03252 // 03253 // Creator : Jason Kraftcheck 03254 // 03255 // Creation Date : 02/28/04 03256 //------------------------------------------------------------------------- 03257 CompositePoint* CompositeEngine::destroy_point_curve( CompositeCurve* curve ) 03258 { 03259 CompositePoint* geom_pt = curve->start_point(); 03260 CompositeCoEdge* coedge = curve->first_coedge(); 03261 CompositeLoop* loop = coedge->get_loop(); 03262 CompositeSurface* surf = loop->get_surface(); 03263 03264 // Make sure topology looks like a point curve 03265 if (curve->num_curves() > 0 || 03266 curve->end_point() != geom_pt || 03267 curve->next_coedge(coedge) != NULL || 03268 loop->next_coedge(coedge) != coedge ) 03269 { 03270 assert( geom_pt == curve->start_point() ); 03271 assert( curve->next_coedge(coedge) == NULL ); 03272 assert( loop->next_coedge(coedge) == coedge ); 03273 return 0; 03274 } 03275 03276 // Destroy point-curve and corresponding topology 03277 curve->remove(coedge); 03278 loop->remove(coedge); 03279 delete coedge; 03280 03281 surf->remove(loop); 03282 delete loop; 03283 03284 curve->start_point(0); 03285 curve->end_point(0); 03286 delete curve; 03287 03288 return geom_pt; 03289 } 03290 03291 03292 03293 CubitStatus CompositeEngine::restore_curve( Curve* curve ) 03294 { 03295 CompositeSurface* new_surf = 0; 03296 03297 // find compostie surface owning the curve 03298 TopologyBridge* bridge = curve; 03299 HiddenEntitySet* owner_set = NULL; 03300 while( bridge && !(owner_set = dynamic_cast<HiddenEntitySet*>(bridge->owner())) ) 03301 { 03302 bridge = dynamic_cast<TopologyBridge*>(bridge->owner()); 03303 } 03304 03305 if( !owner_set ) 03306 return CUBIT_FAILURE; 03307 03308 CompositeSurface* compsurf = dynamic_cast<CompositeSurface*>(owner_set->owner()); 03309 if( !compsurf ) 03310 return CUBIT_FAILURE; 03311 03312 CompositeCurve* compcurve = dynamic_cast<CompositeCurve*>(curve); 03313 if( !compcurve ) 03314 compcurve = dynamic_cast<CompositeCurve*>(curve->owner()); 03315 if( !compcurve ) 03316 return CUBIT_FAILURE; 03317 03318 CompositePoint *start_point = compcurve->start_point(); 03319 CompositePoint *end_point = compcurve->end_point(); 03320 CompositeCurve *stitch_partner = 0; // find_stitch( compcurve ); 03321 03322 // Clean up any null-geometry point-curves attached to the 03323 // start and/or end points. 03324 CompositeCurve* itor = start_point->next_curve(NULL); 03325 while (itor) 03326 { 03327 CompositeCurve* next = start_point->next_curve(itor); 03328 if (itor->num_curves() == 0) 03329 destroy_point_curve(itor); 03330 itor = next; 03331 } 03332 itor = end_point->next_curve(NULL); 03333 while (itor) 03334 { 03335 CompositeCurve* next = end_point->next_curve(itor); 03336 if (itor->num_curves() == 0) 03337 destroy_point_curve(itor); 03338 itor = next; 03339 } 03340 03341 // Check if end points are hidden by a CompositeCurve, and 03342 // if so, split the composite curve so that the end point(s) 03343 // are no longer hidden. 03344 HiddenEntitySet* hs; 03345 if( (hs = dynamic_cast<HiddenEntitySet*>(start_point->owner())) 03346 && dynamic_cast<CompositeCurve*>(hs->owner()) 03347 && !restore_point_in_curve( start_point ) ) 03348 return CUBIT_FAILURE; 03349 if( end_point != start_point 03350 && (hs = dynamic_cast<HiddenEntitySet*>(end_point->owner())) 03351 && dynamic_cast<CompositeCurve*>(hs->owner()) 03352 && !restore_point_in_curve( end_point ) ) 03353 return CUBIT_FAILURE; 03354 03355 // Find which loop(s) to insert CoEdge in, and where in 03356 // the loop(s) to insert it. For the start point of the 03357 // curve, start_loop is the loop containing that point and 03358 // start_prev_coedge and start_next_coedge are the previous 03359 // and next coedges in the loop at that point, respectively. 03360 // Similarly, end_loop, end_prev_coedge and end_next_coedge 03361 // for the end point. 03362 CompositeLoop *start_loop = 0, *end_loop = 0; 03363 CompositeCoEdge *start_prev_coedge = 0, *start_next_coedge = 0; 03364 CompositeCoEdge *end_prev_coedge = 0, *end_next_coedge = 0; 03365 03366 if ( ! find_coedges( compsurf, compcurve, start_point, 03367 start_prev_coedge, start_next_coedge ) ) 03368 return CUBIT_FAILURE; 03369 if( start_prev_coedge ) 03370 { 03371 start_loop = start_prev_coedge->get_loop(); 03372 assert(start_next_coedge && 03373 start_next_coedge->get_loop() == start_loop ); 03374 } 03375 03376 if ( ! find_coedges( compsurf, compcurve, end_point, 03377 end_prev_coedge, end_next_coedge ) ) 03378 return CUBIT_FAILURE; 03379 if( end_prev_coedge ) 03380 { 03381 end_loop = end_prev_coedge->get_loop(); 03382 assert(end_next_coedge && 03383 end_next_coedge->get_loop()== end_loop ); 03384 } 03385 03386 // must be all or none 03387 assert( !start_loop || (start_prev_coedge && start_next_coedge) ); 03388 assert( !end_loop || (end_prev_coedge && end_next_coedge) ); 03389 // closed curve? 03390 assert( (start_point != end_point) || 03391 (start_prev_coedge == end_prev_coedge && start_next_coedge == end_next_coedge) ); 03392 03393 // Find coedges, and un-hide coedegs, curve, and 03394 // end points. 03395 CompositeCoEdge* coedge1 = compcurve->first_coedge(); 03396 while (coedge1 && coedge1->owner() != &compsurf->hidden_entities()) 03397 coedge1 = compcurve->next_coedge(coedge1); 03398 assert( coedge1 ); 03399 CompositeCoEdge* coedge2 = compcurve->next_coedge( coedge1 ); 03400 while (coedge2 && coedge2->owner() != &compsurf->hidden_entities()) 03401 coedge2 = compcurve->next_coedge(coedge2); 03402 if (!coedge2) 03403 { 03404 DLIList<CompositeCurve*> stitched; 03405 compcurve->get_stitched( stitched ); 03406 stitched.remove( compcurve ); 03407 while (!coedge2 && stitched.size()) 03408 { 03409 CompositeCurve* other = stitched.pop(); 03410 coedge2 = other->first_coedge(); 03411 while (coedge2 && coedge2->owner() != &compsurf->hidden_entities()) 03412 coedge2 = other->next_coedge(coedge2); 03413 } 03414 } 03415 assert (coedge2 || compcurve->geometry_type() == POINT_CURVE_TYPE); 03416 compsurf->hidden_entities().restore( coedge1 ); 03417 if (coedge2) // no coedge2 for point-curves 03418 compsurf->hidden_entities().restore( coedge2 ); 03419 03420 compsurf->hidden_entities().restore( compcurve ); 03421 if( compcurve->start_point()->owner() == &(compsurf->hidden_entities()) ) 03422 compsurf->hidden_entities().restore( compcurve->start_point() ); 03423 if( compcurve->end_point()->owner() == &(compsurf->hidden_entities()) ) 03424 compsurf->hidden_entities().restore( compcurve->end_point() ); 03425 if( stitch_partner ) 03426 compsurf->hidden_entities().restore( stitch_partner ); 03427 03428 // If neither point intersected a loop (topologically), then 03429 // create a new loop containing the curve. 03430 if( !start_loop && !end_loop ) 03431 { 03432 // hole 03433 if ( compcurve->start_point() == compcurve->end_point() ) 03434 { 03435 start_loop = new CompositeLoop(); 03436 start_loop->insert_after(coedge1,0); 03437 compsurf->add(start_loop); 03438 if (coedge2) // no coedge2 for point-curves 03439 { 03440 end_loop = new CompositeLoop(); 03441 end_loop->insert_after(coedge2,0); 03442 compsurf->add(end_loop); 03443 if ( CompLoopTool::loop_angle_metric(coedge1) > 03444 CompLoopTool::loop_angle_metric(coedge2) ) 03445 { 03446 compsurf->remove(end_loop); 03447 new_surf = split_surface(compsurf, start_loop, end_loop); 03448 } 03449 else 03450 { 03451 compsurf->remove(start_loop); 03452 new_surf = split_surface(compsurf, end_loop, start_loop); 03453 } 03454 } 03455 } 03456 // hardline 03457 else 03458 { 03459 CompositeLoop* new_loop = new CompositeLoop(); 03460 new_loop->insert_after( coedge1, 0 ); 03461 new_loop->insert_after( coedge2, coedge1 ); 03462 compsurf->add( new_loop ); 03463 } 03464 } 03465 03466 // If only one of the end points intersected a loop, then 03467 // create a sipe in that loop. 03468 else if( !start_loop || !end_loop ) 03469 { 03470 CompositeCoEdge* prev; 03471 CompositeLoop* loop; 03472 if( start_loop ) 03473 { 03474 loop = start_loop; 03475 prev = start_prev_coedge; 03476 } 03477 else 03478 { 03479 loop = end_loop; 03480 prev = end_prev_coedge; 03481 } 03482 03483 if( coedge1->start_point() == prev->end_point() ) 03484 { 03485 loop->insert_after( coedge1, prev ); 03486 loop->insert_after( coedge2, coedge1 ); 03487 } 03488 else 03489 { 03490 assert( coedge2->start_point() == prev->end_point() ); 03491 loop->insert_after( coedge2, prev ); 03492 loop->insert_after( coedge1, coedge2 ); 03493 } 03494 } 03495 03496 // If the end points of the curve intersected different 03497 // loops, combine the loops such that the curve becomes 03498 // a "bridge" between them. 03499 else if( start_loop != end_loop ) 03500 { 03501 CompositeCoEdge* prev = start_prev_coedge; 03502 CompositeCoEdge* coedge = end_next_coedge; 03503 CompositeCoEdge* next = 0; 03504 03505 // Which of the two coedges for the curve we are 03506 // restoring do we want to begin with (and store 03507 // the other as other_coedge). 03508 CompositeCoEdge* other_coedge = NULL; 03509 if( coedge1->start_point() == prev->end_point() ) 03510 { 03511 start_loop->insert_after( coedge1, prev ); 03512 prev = coedge1; 03513 other_coedge = coedge2; 03514 } 03515 else if( coedge2->start_point() == prev->end_point() ) 03516 { 03517 start_loop->insert_after( coedge2, prev ); 03518 prev = coedge2; 03519 other_coedge = coedge1; 03520 } 03521 else assert( 0 ); 03522 03523 while( end_loop->first_coedge() ) // while loop has coedges 03524 { 03525 next = end_loop->next_coedge( coedge ); 03526 end_loop->remove( coedge ); 03527 start_loop->insert_after( coedge, prev ); 03528 prev = coedge; 03529 coedge = next; 03530 } 03531 03532 // The other coedge for the curve we are restoring... 03533 start_loop->insert_after( other_coedge, prev ); 03534 03535 assert( end_loop->num_coedges() == 0 ); 03536 compsurf->remove( end_loop ); 03537 delete end_loop; 03538 } 03539 03540 // If both end points of the curve intersected the same 03541 // loop, then split the loop (and the composite surface) 03542 // into two. 03543 else 03544 { 03545 assert( start_loop == end_loop ); 03546 03547 // Special case: 03548 // Hole intersecting original loop at one point 03549 // (when loop is split, oringinal loop has all 03550 // original coedges, and new loop has only the 03551 // curve we are restoring) Figure out which 03552 // coedge belongs in the hole. 03553 if( coedge1->start_point() == coedge1->end_point() ) 03554 { 03555 assert( start_next_coedge == end_next_coedge ); 03556 assert( start_prev_coedge == end_prev_coedge ); 03557 03558 CubitVector prev_tan, coe1_tan, coe2_tan, norm, junk; 03559 CubitVector point = coedge1->start_point()->coordinates(); 03560 start_prev_coedge->get_curve()->closest_point( point, junk, &prev_tan ); 03561 if( start_prev_coedge->sense() == CUBIT_FORWARD ) // yes, forward!!! 03562 prev_tan *= -1.0; 03563 coedge1->get_curve()->closest_point( point, junk, &coe1_tan ); 03564 coe2_tan = coe1_tan; 03565 if( coedge1->sense() == CUBIT_REVERSED ) 03566 coe1_tan *= -1.0; 03567 if( coedge2->sense() == CUBIT_REVERSED ) 03568 coe2_tan *= -1.0; 03569 compsurf->closest_point( point, 0, &norm ); 03570 03571 double angle1 = norm.vector_angle( prev_tan, coe1_tan ); 03572 double angle2 = norm.vector_angle( prev_tan, coe2_tan ); 03573 03574 if( angle2 < angle1 ) 03575 { 03576 CompositeCoEdge* temp = coedge2; 03577 coedge2 = coedge1; 03578 coedge1 = temp; 03579 } 03580 } 03581 03582 // Normal case (not a hole) 03583 else 03584 { 03585 // Make sure coedge1 is the reverse one 03586 if( coedge1->sense() == CUBIT_FORWARD ) 03587 std::swap(coedge1,coedge2); 03588 } 03589 03590 end_loop = new CompositeLoop(); 03591 start_loop->insert_after( coedge1, end_prev_coedge ); 03592 end_loop->insert_after( coedge2, 0 ); 03593 03594 CompositeCoEdge* coedge = end_next_coedge; 03595 CompositeCoEdge* prev = coedge2; 03596 while( coedge != start_next_coedge ) 03597 { 03598 CompositeCoEdge* next = start_loop->next_coedge( coedge ); 03599 start_loop->remove( coedge ); 03600 end_loop->insert_after( coedge, prev ); 03601 prev = coedge; 03602 coedge = next; 03603 } 03604 03605 new_surf = split_surface( compsurf, start_loop, end_loop ); 03606 03607 } 03608 03609 if( new_surf ) 03610 { 03611 if( compsurf->next_co_surface() ) 03612 { 03613 CompositeCoSurf* cos = 0; 03614 while( (cos = compsurf->next_co_surface(cos)) ) 03615 cos->get_shell()->add( new_surf, cos->sense() ); 03616 } 03617 03618 if( ! new_surf->has_hidden_entities() && 03619 ! new_surf->next_co_surface(0) ) 03620 remove_composite( new_surf ); 03621 } 03622 03623 if( ! compsurf->has_hidden_entities() && 03624 ! compsurf->next_co_surface(0) ) 03625 remove_composite( compsurf ); 03626 03627 return CUBIT_SUCCESS; 03628 } 03629 03630 03631 //------------------------------------------------------------------------- 03632 // Purpose : Given a point that intersects a loop in the passed 03633 // surface, find the location in that loop at which the 03634 // passed curve should be inserted. If there are only two 03635 // coedges in the loop at the passed point, then the answer 03636 // is obvious. If there is a sipe at the point, then use 03637 // topological information of underlying real surfaces to 03638 // determine the two coedges between which the new curve 03639 // should be inserted. 03640 // 03641 // Special Notes : 03642 // 03643 // Creator : Jason Kraftcheck 03644 // 03645 // Creation Date : 03/19/03 03646 //------------------------------------------------------------------------- 03647 CubitStatus CompositeEngine::find_coedges( CompositeSurface* surface, 03648 CompositeCurve* curve, 03649 CompositePoint* point, 03650 CompositeCoEdge*& previous, 03651 CompositeCoEdge*& next ) 03652 { 03653 const char* const bad_loop_message = "Internal error: Invalid loop. (%s:%d)\n"; 03654 03655 // Find list of all coedges around passed point 03656 // and in passed surface. 03657 DLIList<CompositeCoEdge*> point_coedges; 03658 CompositeCurve* pt_curve = 0; 03659 while ( (pt_curve = point->next_curve(pt_curve)) ) 03660 { 03661 CompositeCoEdge* coedge = 0; 03662 while ( (coedge = pt_curve->next_coedge(coedge)) ) 03663 { 03664 if (coedge->get_loop() && coedge->get_loop()->get_surface() == surface) 03665 point_coedges.append(coedge); 03666 } 03667 } 03668 03669 // Point is at end of a sipe/hardline 03670 if ( point_coedges.size() == 0 ) 03671 { 03672 previous = next = 0; 03673 return CUBIT_SUCCESS; 03674 } 03675 03676 // One coedge - closed curve 03677 if ( point_coedges.size() == 1 && 03678 point_coedges.get()->start_point() == 03679 point_coedges.get()->end_point() ) 03680 { 03681 previous = next = point_coedges.get(); 03682 return CUBIT_SUCCESS; 03683 } 03684 03685 // Broken loop? 03686 if ( point_coedges.size() % 2 != 0 ) 03687 { 03688 PRINT_ERROR(bad_loop_message,__FILE__,__LINE__); 03689 assert(0); 03690 return CUBIT_FAILURE; 03691 } 03692 03693 // If only two coedges, then we're done 03694 if ( point_coedges.size() == 2 ) 03695 { 03696 previous = point_coedges.get(); 03697 next = point_coedges.next(); 03698 03699 if ( previous->start_point() == point ) 03700 std::swap(previous, next); 03701 03702 return CUBIT_SUCCESS; 03703 } 03704 03705 // Find previous/next coedges by using order of 03706 // coedges about point in underlying surfaces. 03707 // Coedges must occur in clock-wise order about point. 03708 03709 // Get the real curve at the point 03710 int curve_index = point == curve->start_point() ? 0 : curve->num_curves() - 1; 03711 Curve* real_curve = curve->get_curve(curve_index); 03712 03713 // Get two coedges in composite 03714 DLIList<TopologyBridge*> coedge_bridges, loop_bridges(1), surface_bridges(1); 03715 real_curve->get_parents_virt(coedge_bridges); 03716 DLIList<CoEdgeSM*> curve_coedges; 03717 while (coedge_bridges.size()) 03718 { 03719 TopologyBridge* coe_bridge = coedge_bridges.pop(); 03720 03721 loop_bridges.clean_out(); 03722 surface_bridges.clean_out(); 03723 03724 coe_bridge->get_parents_virt(loop_bridges); 03725 assert(loop_bridges.size() == 1); 03726 03727 loop_bridges.get()->get_parents_virt(surface_bridges); 03728 assert(surface_bridges.size() == 1); 03729 03730 if ( surface->contains_bridge(surface_bridges.get()) ) 03731 { 03732 curve_coedges.append(dynamic_cast<CoEdgeSM*>(coe_bridge)); 03733 } 03734 } 03735 if ( curve_coedges.size() != 2 ) 03736 { 03737 PRINT_ERROR(bad_loop_message,__FILE__,__LINE__); 03738 assert(0); 03739 return CUBIT_FAILURE; 03740 } 03741 03742 // Assign coedges such that prev_coe_sm goes "out of" 03743 // the point and next_coe_sm goes "into" the point. 03744 // (Unless surface sense is reversed in composite surface.) 03745 curve_coedges.reset(); 03746 CoEdgeSM *prev_coe_sm = curve_coedges.get(); 03747 CoEdgeSM *next_coe_sm = curve_coedges.next(); 03748 CompositeCoEdge* prev_owner = dynamic_cast<CompositeCoEdge*>(prev_coe_sm->owner()); 03749 #ifndef NDEBUG 03750 CompositeCoEdge* next_owner = dynamic_cast<CompositeCoEdge*>(next_coe_sm->owner()); 03751 assert( prev_owner && next_owner ); 03752 #endif 03753 if ( prev_owner->start_point() == point ) 03754 { 03755 #ifndef NDEBUG 03756 assert(next_owner->end_point() == point); 03757 #endif 03758 } 03759 else 03760 { 03761 #ifndef NDEBUG 03762 assert(next_owner->start_point() == point); 03763 assert(prev_owner->end_point() == point); 03764 #endif 03765 std::swap(prev_coe_sm, next_coe_sm); 03766 } 03767 03768 // Now iterate through real coedges around point to 03769 // find the next/prev composite coedges. 03770 CompositeCoEdge* prev_result 03771 = find_next_point_coedge( surface, prev_coe_sm, point, point_coedges ); 03772 CompositeCoEdge* next_result 03773 = find_next_point_coedge( surface, next_coe_sm, point, point_coedges ); 03774 03775 if( !prev_result || !next_result ) 03776 { 03777 PRINT_ERROR("Internal error: Invalid composite. (%s:%d)\n",__FILE__,__LINE__); 03778 return CUBIT_FAILURE; 03779 } 03780 03781 return CUBIT_SUCCESS; 03782 } 03783 03784 //------------------------------------------------------------------------- 03785 // Purpose : Find next coedge by traversing real coedges on 03786 // surfaces hidden by composite. 03787 // 03788 // Special Notes : 03789 // 03790 // Creator : Jason Kraftcheck 03791 // 03792 // Creation Date : 03/19/03 03793 //------------------------------------------------------------------------- 03794 CompositeCoEdge* CompositeEngine::find_next_point_coedge( 03795 CompositeSurface* const compsurf, 03796 CoEdgeSM* const first_coedge, 03797 CompositePoint* point, 03798 DLIList<CompositeCoEdge*>& point_coedges ) 03799 { 03800 DLIList<TopologyBridge*> loop_bridges(1), coedge_bridges, curve_pts(2); 03801 CoEdgeSM* coedge = first_coedge; 03802 03803 coedge_bridges.clean_out(); 03804 coedge->get_children(coedge_bridges,true,COMPOSITE_LAYER-1); 03805 assert(coedge_bridges.size() == 1); 03806 Curve* curvesm = dynamic_cast<Curve*>(coedge_bridges.get()); 03807 03808 do 03809 { 03810 // Get loop from coedge 03811 loop_bridges.clean_out(); 03812 coedge->get_parents_virt(loop_bridges); 03813 assert(loop_bridges.size() == 1); 03814 LoopSM* loop_sm = dynamic_cast<LoopSM*>(loop_bridges.get()); 03815 03816 // Make sure we're still inside the composite. 03817 // It's a bug if this check fails. 03818 loop_bridges.clean_out(); 03819 loop_sm->get_parents_virt(loop_bridges); 03820 if ( !compsurf->contains_bridge(loop_bridges.get()) ) 03821 { assert(0); break; } 03822 03823 // Get direction of curve wrt point : forward if the 03824 // curve ends at the point or reverse if it begins at 03825 // the point. 03826 curve_pts.clean_out(); 03827 curvesm->get_children(curve_pts,true,COMPOSITE_LAYER-1); 03828 curve_pts.reset(); 03829 CubitSense curve_sense; 03830 if ( curve_pts.next()->owner() == point ) 03831 curve_sense = CUBIT_FORWARD; 03832 else if( curve_pts.get()->owner() == point ) 03833 curve_sense = CUBIT_REVERSED; 03834 else 03835 { assert(0); break; } //bug - shouldn't happen 03836 03837 // Get the next coedge in the loop. If the coedge 03838 // begins at the point, then the adjacent coedge 03839 // is the previous one in the loop. Otherwise 03840 // it is the next one in the loop. 03841 coedge_bridges.clean_out(); 03842 loop_sm->get_children(coedge_bridges,true,COMPOSITE_LAYER-1); 03843 coedge_bridges.move_to(coedge); 03844 assert(coedge_bridges.get() == coedge); 03845 if ( coedge->sense() == curve_sense ) 03846 coedge = dynamic_cast<CoEdgeSM*>(coedge_bridges.next()); 03847 else 03848 coedge = dynamic_cast<CoEdgeSM*>(coedge_bridges.prev()); 03849 03850 // Are we done? This is the real end condition. 03851 // Any other return path is an error. 03852 CompositeCoEdge* result = dynamic_cast<CompositeCoEdge*>(coedge->owner()); 03853 assert(!!result); 03854 if ( point_coedges.is_in_list(result) ) 03855 return result; 03856 03857 // get the curve for the current coedge 03858 coedge_bridges.clean_out(); 03859 coedge->get_children(coedge_bridges,true,COMPOSITE_LAYER-1); 03860 assert(coedge_bridges.size() == 1); 03861 curvesm = dynamic_cast<Curve*>(coedge_bridges.get()); 03862 03863 // Get the other coedge on the curve 03864 coedge_bridges.clean_out(); 03865 curvesm->get_parents_virt(coedge_bridges); 03866 if ( coedge_bridges.size() != 2 ) 03867 break; // Reached boundary of composite 03868 coedge_bridges.move_to( coedge ); 03869 assert(coedge_bridges.get() == coedge ); 03870 coedge = dynamic_cast<CoEdgeSM*>(coedge_bridges.next()); 03871 03872 } while( coedge != first_coedge ); 03873 03874 return 0; 03875 } 03876 03877 03878 03879 03880 03881 //------------------------------------------------------------------------- 03882 // Purpose : 03883 // 03884 // Special Notes : 03885 // 03886 // Creator : Jason Kraftcheck 03887 // 03888 // Creation Date : 03889 //------------------------------------------------------------------------- 03890 CompositeSurface* CompositeEngine::split_surface( 03891 CompositeSurface* surf_to_split, 03892 CompositeLoop* loop_on_orig, 03893 CompositeLoop* loop_on_new ) 03894 { 03895 int i; 03896 03897 DLIList<CoEdgeSM*> front_list; 03898 DLIList<TopologyBridge*> bridge_list, loop_list, coedge_list; 03899 DLIList<TopologyBridge*> hidden_loops_to_move; 03900 DLIList<Surface*> surfs_to_move; 03901 03902 // Do advancing front across surfaces underlying composite surface 03903 // to find which must be moved to the new composite. 03904 03905 // Begin with the coedges in loop_on_new. 03906 CompositeCoEdge* coedge = loop_on_new->first_coedge(); 03907 do 03908 { 03909 for( i = 0; i < coedge->num_coedges(); i++ ) 03910 front_list.append( coedge->get_coedge(i) ); 03911 coedge = loop_on_new->next_coedge( coedge ); 03912 } while( coedge != loop_on_new->first_coedge() ); 03913 03914 // Loop until front_list is empty 03915 while( front_list.size() ) 03916 { 03917 CoEdgeSM* coe_real = front_list.pop(); 03918 03919 // Loop and Surface from CoEdge 03920 bridge_list.clean_out(); 03921 coe_real->get_parents_virt( bridge_list ); 03922 assert( bridge_list.size() == 1 ); 03923 TopologyBridge* loop = bridge_list.get(); 03924 bridge_list.clean_out(); 03925 loop->get_parents_virt( bridge_list ); 03926 if( bridge_list.size() != 1 ) 03927 { 03928 assert( loop == loop_on_new ); 03929 assert( bridge_list.size() == 0 ); 03930 continue; 03931 } 03932 03933 Surface* surf = dynamic_cast<Surface*>(bridge_list.get()); 03934 assert( surf!= NULL ); 03935 03936 if( surf->owner() != surf_to_split ) 03937 continue; 03938 03939 // Add surface to list of Surfaces to move to new composite 03940 surfs_to_move.append_unique( surf ); 03941 03942 // Get list of all surface coedges (coedge_list) 03943 // and all loops to hidden_loops_to_move 03944 loop_list.clean_out(); 03945 surf->get_children_virt( loop_list ); 03946 for( i = loop_list.size(); i--; ) 03947 { 03948 TopologyBridge* loop_bridge = loop_list.get_and_step(); 03949 if( hidden_loops_to_move.is_in_list( loop_bridge ) ) 03950 continue; 03951 hidden_loops_to_move.append( loop_bridge ); 03952 bridge_list.clean_out(); 03953 loop_bridge->get_children( bridge_list, true, COMPOSITE_LAYER-1 ); 03954 coedge_list += bridge_list; 03955 } 03956 03957 // For each coedge on the surface (all coedges in coedge_list), 03958 // get the curve and search for any other coedges that are 03959 // parents of that curve and children of a surface hidden by 03960 // the composite. Add them to front_list. 03961 while( coedge_list.size() ) 03962 { 03963 TopologyBridge* coe_bridge = coedge_list.pop(); 03964 bridge_list.clean_out(); 03965 coe_bridge->get_children_virt( bridge_list ); 03966 assert( bridge_list.size() == 1 ); 03967 TopologyBridge* curve_bridge = bridge_list.get(); 03968 bridge_list.clean_out(); 03969 curve_bridge->get_parents_virt( bridge_list ); 03970 03971 while( bridge_list.size() ) 03972 { 03973 TopologyBridge* other_coe = bridge_list.pop(); 03974 if( other_coe == coe_bridge ) 03975 continue; 03976 03977 CompositeCoEdge* compcoe = dynamic_cast<CompositeCoEdge*>(other_coe); 03978 if( !compcoe ) 03979 { 03980 compcoe = dynamic_cast<CompositeCoEdge*>(other_coe->owner()); 03981 } 03982 if( !compcoe || compcoe->get_loop() != loop_on_orig ) 03983 front_list.append( dynamic_cast<CoEdgeSM*>( other_coe ) ); 03984 } 03985 } 03986 } 03987 03988 // Check if surface needs to be split. A new, closed loop 03989 // does not always indicate the surface needs to be split. 03990 // See PR#2140 for an example. 03991 if (surfs_to_move.size() == surf_to_split->num_surfs()) 03992 { 03993 surf_to_split->add( loop_on_new ); 03994 return 0; 03995 } 03996 03997 // Split the composite (pass in indices of surfaces that 03998 // should be in new composite rather than old.) 03999 VGArray<int> index_array( surfs_to_move.size() ); 04000 for( i = 0; i < surfs_to_move.size(); i++ ) 04001 index_array[i] = surf_to_split->index_of( surfs_to_move.get_and_step() ); 04002 CompositeSurface* new_surf = surf_to_split->split( index_array ); 04003 if( !new_surf ) 04004 { 04005 surf_to_split->add( loop_on_new ); 04006 return 0; 04007 } 04008 04009 assert( new_surf->num_surfs() && surf_to_split->num_surfs() ); 04010 new_surf->add( loop_on_new ); 04011 04012 // Move hidden coedges from old surface's hidden set to 04013 // new surface. 04014 HiddenEntitySet* new_set = &(new_surf->hidden_entities()); 04015 HiddenEntitySet* old_set = &(surf_to_split->hidden_entities()); 04016 for ( i = 0; i < new_surf->num_surfs(); i++ ) 04017 { 04018 loop_list.clean_out(); 04019 new_surf->get_surface(i)->get_children_virt(loop_list); 04020 for ( int j = loop_list.size(); j--; ) 04021 { 04022 coedge_list.clean_out(); 04023 loop_list.get_and_step()->get_children( coedge_list, true, COMPOSITE_LAYER ); 04024 for ( int k = coedge_list.size(); k--; ) 04025 { 04026 TopologyBridge* coedge_ptr = coedge_list.get_and_step(); 04027 if ( coedge_ptr->owner() == old_set ) 04028 { 04029 old_set->restore(coedge_ptr); 04030 new_set->hide(coedge_ptr); 04031 } 04032 } 04033 } 04034 } 04035 04036 04037 // Move hidden curves from old surface's hidden set to 04038 // new surface. 04039 DLIList<Curve*> hidden_curves; 04040 old_set->hidden_curves( hidden_curves ); 04041 for( i = hidden_curves.size(); i--; ) 04042 { 04043 Curve* curve = hidden_curves.get_and_step(); 04044 CompositeCurve* comp_curve = dynamic_cast<CompositeCurve*>(curve); 04045 assert(!!comp_curve); 04046 04047 bool all_new = true; 04048 bool all_old = true; 04049 CompositeCoEdge* coedge_ptr = 0; 04050 while( (coedge_ptr = comp_curve->next_coedge(coedge_ptr)) ) 04051 { 04052 if( coedge_ptr->owner() != new_set ) 04053 all_new = false; 04054 if( coedge_ptr->owner() != old_set ) 04055 all_old = false; 04056 } 04057 if( ! all_old ) 04058 old_set->restore( curve ); 04059 if( all_new ) 04060 new_set->hide( curve ); 04061 } 04062 04063 // Move hidden points from old surface's hidden set to 04064 // new surface. 04065 DLIList<TBPoint*> hidden_points; 04066 old_set->hidden_points( hidden_points ); 04067 for( i = hidden_points.size(); i--; ) 04068 { 04069 TBPoint* point = hidden_points.get_and_step(); 04070 CompositePoint* comp_pt = dynamic_cast<CompositePoint*>(point); 04071 assert(!!comp_pt); 04072 04073 CompositeCurve* curve = 0; 04074 bool all_new = true; 04075 bool all_old = true; 04076 while ( (curve = comp_pt->next_curve(curve)) ) 04077 { 04078 if ( curve->owner() != new_set ) 04079 all_new = false; 04080 if ( curve->owner() != old_set ) 04081 all_old = false; 04082 } 04083 04084 if( ! all_old ) 04085 old_set->restore( point ); 04086 if( all_new ) 04087 new_set->hide( point ); 04088 } 04089 04090 04091 04092 // figure out which visible loops need to be moved 04093 DLIList<CompositeLoop*> loops_to_move; 04094 for( CompositeLoop* loop = surf_to_split->first_loop(); 04095 loop != 0; 04096 loop = loop->next_loop() ) 04097 { 04098 CompositeCoEdge* a_coedge = loop->first_coedge(); 04099 CoEdgeSM* real_coe = a_coedge->get_coedge(0); 04100 assert( real_coe!= NULL ); 04101 bridge_list.clean_out(); 04102 real_coe->get_parents_virt( bridge_list ); 04103 assert( bridge_list.size() == 1 ); 04104 TopologyBridge* loop_bridge = bridge_list.get(); 04105 bridge_list.clean_out(); 04106 loop_bridge->get_parents_virt( bridge_list ); 04107 Surface* surf = dynamic_cast<Surface*>(bridge_list.get()); 04108 assert( surf!= NULL ); 04109 if( surf->owner() == new_surf ) 04110 loops_to_move.append( loop ); 04111 } 04112 04113 // move visible loops to new surface 04114 while( loops_to_move.size() ) 04115 { 04116 CompositeLoop* loop = loops_to_move.pop(); 04117 surf_to_split->remove( loop ); 04118 new_surf->add( loop ); 04119 } 04120 04121 assert( loop_on_orig->get_surface() == surf_to_split ); 04122 return new_surf; 04123 } 04124 04125 04126 04127 //------------------------------------------------------------------------- 04128 // Purpose : Composite Curves 04129 // 04130 // Special Notes : 04131 // 04132 // Creator : Jason Kraftcheck 04133 // 04134 // Creation Date : 04135 //------------------------------------------------------------------------- 04136 CompositeCurve* CompositeEngine::remove_point( TBPoint* dead_point, 04137 bool remove_partition, 04138 Curve* survivor ) 04139 { 04140 if( dynamic_cast<CompositePoint*>(dead_point->owner()) ) 04141 dead_point = dynamic_cast<TBPoint*>(dead_point->owner()); 04142 04143 DLIList<TopologyBridge*> query_results; 04144 dead_point->get_parents_virt( query_results ); 04145 if( query_results.size() != 2 ) 04146 return 0; 04147 04148 Curve* curve1 = dynamic_cast<Curve*>(query_results.get_and_step()); 04149 Curve* curve2 = dynamic_cast<Curve*>(query_results.get_and_step()); 04150 assert( curve1 && curve2 ); 04151 04152 query_results.clean_out(); 04153 curve1->get_children( query_results, COMPOSITE_LAYER ); 04154 assert( query_results.size() == 2 && query_results.move_to( dead_point ) ); 04155 query_results.move_to( dead_point ); 04156 TBPoint* other1 = dynamic_cast<TBPoint*>(query_results.step_and_get()); 04157 04158 query_results.clean_out(); 04159 curve2->get_children( query_results, COMPOSITE_LAYER ); 04160 assert( query_results.size() == 2 && query_results.move_to( dead_point ) ); 04161 query_results.move_to( dead_point ); 04162 TBPoint* other2 = dynamic_cast<TBPoint*>(query_results.step_and_get()); 04163 04164 // If curves form a closed two-curve loop, we need to 04165 // specify which point to keep. 04166 TBPoint* keep = other1 == other2 ? other1 : 0; 04167 if (survivor == curve2) std::swap(curve1, curve2); 04168 return composite( curve1, curve2, keep, remove_partition ); 04169 } 04170 04171 //------------------------------------------------------------------------- 04172 // Purpose : Remove curve partitions beneath a composite curve 04173 // 04174 // Special Notes : 04175 // 04176 // Creator : Jason Kraftcheck 04177 // 04178 // Creation Date : 03/11/03 04179 //------------------------------------------------------------------------- 04180 CubitStatus CompositeEngine::remove_partition_point( CompositePoint* comp ) 04181 { 04182 PartitionPoint* pt = dynamic_cast<PartitionPoint*>(comp->get_point()); 04183 if( !pt || pt->real_point() ) 04184 return CUBIT_SUCCESS; 04185 04186 if( comp->next_curve() ) 04187 return CUBIT_FAILURE; 04188 04189 if ( !PartitionEngine::instance().remove_point( pt ) ) 04190 return CUBIT_FAILURE; 04191 04192 assert( !comp->get_point() ); 04193 clean_out_deactivated_geometry(); 04194 04195 return CUBIT_SUCCESS; 04196 } 04197 04198 //------------------------------------------------------------------------- 04199 // Purpose : Remove surface partitions beneath a composite surface 04200 // 04201 // Special Notes : 04202 // 04203 // Creator : Jason Kraftcheck 04204 // 04205 // Creation Date : 03/11/03 04206 //------------------------------------------------------------------------- 04207 CubitStatus CompositeEngine::remove_partition_curves( CompositeCurve* curve ) 04208 { 04209 if( ! dynamic_cast<HiddenEntitySet*>(curve->owner()) ) 04210 { assert(0); return CUBIT_FAILURE; } 04211 04212 DLIList<CompositeCurve*> hidden_curves; 04213 hidden_curves.append( curve ); 04214 04215 // Split composite such that each partition curve to be removed 04216 // is owned by a seperate composite curve. Put the partitition 04217 // curves in dead_curves and their owning composite curves in 04218 // dead_composites. 04219 int i; 04220 CubitStatus result = CUBIT_SUCCESS; 04221 DLIList<PartitionCurve*> dead_curves; 04222 while( hidden_curves.size() ) 04223 { 04224 CompositeCurve* comp = hidden_curves.pop(); 04225 04226 // If this curve has a single underlying curve, 04227 // we're done with it. Add the underlying curve 04228 // to the dead curve list if it is a PartitionCurve 04229 // and move on to the next composite curve. 04230 if( comp->num_curves() == 1 ) 04231 { 04232 SegmentedCurve* segcurve = dynamic_cast<SegmentedCurve*>(comp->get_curve(0)); 04233 if( segcurve ) 04234 { 04235 dead_curves.append(segcurve); 04236 } 04237 continue; 04238 } 04239 04240 // Search for a partition curve in the composite 04241 for ( i = 1; i < comp->num_curves(); i++ ) 04242 if( dynamic_cast<SegmentedCurve*>(comp->get_curve(i)) ) 04243 break; 04244 04245 // Composite doesn't contain any partition curves. 04246 // Move on to the next composite curve. 04247 if( i == comp->num_curves() ) 04248 continue; 04249 04250 // Split composite curve at the partition curve. 04251 Curve* r1, *r2; 04252 if ( !split( comp, i, r1, r2 ) ) 04253 { 04254 result = CUBIT_FAILURE; 04255 continue; 04256 } 04257 04258 // Add the resulting composites back onto hidden_curves. 04259 // Continue processing them until all partitions are in their 04260 // own composite, or the composite contains no more partitions. 04261 CompositeCurve* comp1 = dynamic_cast<CompositeCurve*>(r1); 04262 CompositeCurve* comp2 = dynamic_cast<CompositeCurve*>(r2); 04263 assert(comp1 && comp2); 04264 hidden_curves.append(comp1); 04265 hidden_curves.append(comp2); 04266 } 04267 04268 04269 // Now actually remove the partition curves 04270 while ( dead_curves.size() ) 04271 if ( ! PartitionEngine::instance().remove_curve( dead_curves.pop() ) ) 04272 result = CUBIT_FAILURE; 04273 04274 // Last, delete the remaining composite curves 04275 clean_out_deactivated_geometry(); 04276 04277 return result; 04278 } 04279 04280 //------------------------------------------------------------------------- 04281 // Purpose : Create a point-curve given a point hidden by a composite 04282 // surface. 04283 // 04284 // Special Notes : 04285 // 04286 // Creator : Jason Kraftcheck 04287 // 04288 // Creation Date : 02/27/04 04289 //------------------------------------------------------------------------- 04290 CompositeCurve* CompositeEngine::restore_point_in_surface( TBPoint* pt ) 04291 { 04292 // If real point is hidden by a composite surface, it should 04293 // have already been replaced by a composite point. Get the 04294 // composite point. 04295 CompositePoint* point = dynamic_cast<CompositePoint*>(pt); 04296 if (!point && !(point = dynamic_cast<CompositePoint*>(pt->owner()))) 04297 return NULL; 04298 04299 // Get the surface hiding the point. 04300 HiddenEntitySet* hidden_set = dynamic_cast<HiddenEntitySet*>(point->owner()); 04301 if (!hidden_set) 04302 return NULL; 04303 04304 CompositeSurface* surface = dynamic_cast<CompositeSurface*>(hidden_set->owner()); 04305 if (!surface) 04306 return NULL; 04307 04308 // Check if the point is already owned by a point curve. 04309 CompositeCurve* curve = 0; 04310 while ( (curve = point->next_curve(curve)) ) 04311 if (curve->geometry_type() == POINT_CURVE_TYPE) 04312 return restore_curve(curve) ? curve : NULL; 04313 04314 // Construct null-geometry composite curve 04315 surface->hidden_entities().restore(point); 04316 curve = new CompositeCurve(point); 04317 CompositeCoEdge* coedge = new CompositeCoEdge(curve); 04318 CompositeLoop* loop = new CompositeLoop(); 04319 loop->insert_after( coedge, NULL ); 04320 surface->add(loop); 04321 return curve; 04322 } 04323 04324 //------------------------------------------------------------------------- 04325 // Purpose : Create a new cosurface with appropriate sense 04326 // 04327 // Special Notes : 04328 // 04329 // Creator : Jason Kraftcheck 04330 // 04331 // Creation Date : 09/27/04 04332 //------------------------------------------------------------------------- 04333 static CompositeCoSurf* cme_create_cosurf( CompositeLump* lump, 04334 CompositeSurface* surf ) 04335 { 04336 Surface* real_surf = surf->get_surface(0); 04337 04338 DLIList<TopologyBridge*> shells, lumps(1); 04339 real_surf->get_parents( shells ); 04340 while (shells.size()) 04341 { 04342 TopologyBridge* shell = shells.pop(); 04343 lumps.clean_out(); 04344 shell->get_parents( lumps ); 04345 assert( lumps.size() == 1 ); 04346 TopologyBridge* real_lump = lumps.pop(); 04347 if (real_lump->owner() == lump) 04348 { 04349 CubitSense sense = real_surf->get_shell_sense( dynamic_cast<ShellSM*>(shell) ); 04350 if (sense == CUBIT_UNKNOWN) 04351 sense = CUBIT_FORWARD; 04352 else if (surf->get_sense(0) == CUBIT_REVERSED) 04353 sense = (sense == CUBIT_REVERSED) ? CUBIT_FORWARD : CUBIT_REVERSED; 04354 04355 CompositeCoSurf* result = new CompositeCoSurf(sense); 04356 surf->add( result ); 04357 return result; 04358 } 04359 } 04360 04361 return NULL; 04362 } 04363 04364 //------------------------------------------------------------------------- 04365 // Purpose : Restore a surface hidden by a composite volume 04366 // 04367 // Special Notes : 04368 // 04369 // Creator : Jason Kraftcheck 04370 // 04371 // Creation Date : 09/27/04 04372 //------------------------------------------------------------------------- 04373 CubitStatus CompositeEngine::restore_surface( Surface* surf, 04374 Surface*& stitch_partner ) 04375 { 04376 // find composite lump owning the curve 04377 TopologyBridge* bridge = surf; 04378 HiddenEntitySet* owner_set = NULL; 04379 while( bridge && !(owner_set = dynamic_cast<HiddenEntitySet*>(bridge->owner())) ) 04380 { 04381 bridge = dynamic_cast<TopologyBridge*>(bridge->owner()); 04382 } 04383 04384 if( !owner_set ) 04385 return CUBIT_FAILURE; 04386 04387 CompositeLump* lump = dynamic_cast<CompositeLump*>(owner_set->owner()); 04388 if( !lump ) 04389 return CUBIT_FAILURE; 04390 04391 CompositeSurface* surf1 = dynamic_cast<CompositeSurface*>(surf); 04392 if( !surf1 ) 04393 surf1 = dynamic_cast<CompositeSurface*>(surf1->owner()); 04394 if( !surf1 ) 04395 return CUBIT_FAILURE; 04396 04397 // Check if and curves are hidden by a CompositeSurface, and 04398 // if so, split the composite surface so that the curve(s) 04399 // are no longer hidden. 04400 HiddenEntitySet* hs; 04401 CompositeLoop* loop; 04402 CompositeCoEdge* coedge; 04403 for (loop = surf1->first_loop(); loop; loop = surf1->next_loop(loop)) 04404 { 04405 coedge = loop->first_coedge(); 04406 do { 04407 CompositeCurve* curv = coedge->get_curve(); 04408 if ( (hs = dynamic_cast<HiddenEntitySet*>(curv->owner())) 04409 && dynamic_cast<CompositeSurface*>(hs->owner()) 04410 && !restore_curve(curv)) 04411 return CUBIT_FAILURE; 04412 } while ((coedge = loop->next_coedge(coedge)) != loop->first_coedge()); 04413 } 04414 04415 // Un-hide surf's and children 04416 CompositeSurface* surf2 = surf1->unstitch(); 04417 cme_unhide_surface( surf1 ); 04418 if (surf2 != surf) 04419 cme_unhide_surface( surf2 ); 04420 04421 // Find affected shells. 04422 bool all_connected = true; 04423 DLIList<CompositeShell*> modified_shell_list; 04424 DLIList<CompositeCurve*> curve_list; 04425 for (loop = surf1->first_loop(); loop; loop = surf1->next_loop(loop)) 04426 { 04427 coedge = loop->first_coedge(); 04428 do { 04429 CompositeCurve* curv = coedge->get_curve(); 04430 curv->get_stitched( curve_list ); 04431 bool found_adj_surf = false; 04432 while (curve_list.size()) 04433 { 04434 curv = curve_list.pop(); 04435 CompositeCoEdge* curve_coedge = 0; 04436 while ((curve_coedge = curv->next_coedge(curve_coedge))) 04437 { 04438 if (!curve_coedge->get_loop()) 04439 continue; 04440 04441 CompositeSurface* adj_surf = curve_coedge->get_loop()->get_surface(); 04442 if (adj_surf == surf1 || adj_surf == surf2) 04443 continue; 04444 04445 CompositeCoSurf* cosurf = 0; 04446 while ((cosurf = adj_surf->next_co_surface( cosurf ))) 04447 { 04448 if (cosurf->get_shell()->get_lump() == lump) 04449 { 04450 found_adj_surf = true; 04451 modified_shell_list.append_unique( cosurf->get_shell() ); 04452 } 04453 } 04454 } 04455 } 04456 04457 if (!found_adj_surf) 04458 all_connected = false; 04459 04460 } while ((coedge = loop->next_coedge( coedge )) != loop->first_coedge()); 04461 } 04462 04463 04464 // Create Co-Surfacs 04465 CompositeCoSurf *cosurf2, *cosurf1 = cme_create_cosurf( lump, surf1 ); 04466 if (surf1 == surf2) 04467 { 04468 CubitSense sense = cosurf1->sense() == CUBIT_FORWARD ? 04469 CUBIT_REVERSED : CUBIT_FORWARD; 04470 cosurf2 = new CompositeCoSurf( sense ); 04471 surf2->add( cosurf2 ); 04472 } 04473 else 04474 { 04475 cosurf2 = cme_create_cosurf( lump, surf2 ); 04476 } 04477 04478 04479 CompositeShell* shell_to_split = 0; 04480 if (modified_shell_list.size() == 0) 04481 { 04482 // No adjacent shells -- create void 04483 CompositeShell* shell_to_split = new CompositeShell(); 04484 lump->add( shell_to_split ); 04485 04486 // If surface is closed, set all_connected to true 04487 // to indicate that the volume must be split (to create 04488 // the void) 04489 loop = 0; 04490 all_connected = true; 04491 while ((loop = surf1->next_loop(loop))) 04492 { 04493 coedge = loop->first_coedge(); 04494 do { 04495 CompositeCurve* curv = coedge->get_curve(); 04496 CompositeCoEdge* curv_coedge = 0; 04497 bool closed = false; 04498 while ((curv_coedge = curv->next_coedge(curv_coedge))) 04499 { 04500 if (curv_coedge != coedge && 04501 curv_coedge->get_loop() && 04502 (curv_coedge->get_loop()->get_surface() == surf1 || 04503 curv_coedge->get_loop()->get_surface() == surf2)) 04504 { 04505 closed = true; 04506 break; 04507 } 04508 } 04509 if (!closed) 04510 all_connected = false; 04511 } while ((coedge = loop->next_coedge(coedge)) != loop->first_coedge()); 04512 } 04513 } 04514 else 04515 { 04516 // otherwise combine all connected shells 04517 modified_shell_list.reverse(); 04518 shell_to_split = modified_shell_list.pop(); 04519 while (modified_shell_list.size()) 04520 { 04521 CompositeShell* shell = modified_shell_list.pop(); 04522 while (CompositeCoSurf* cosurf = shell->first_co_surf()) 04523 { 04524 shell->remove( cosurf ); 04525 shell_to_split->add( cosurf ); 04526 } 04527 lump->remove( shell ); 04528 delete shell; 04529 } 04530 } 04531 04532 shell_to_split->add( cosurf1 ); 04533 shell_to_split->add( cosurf2 ); 04534 04535 stitch_partner = surf1 == surf2 ? NULL : surf2; 04536 if (all_connected) 04537 { 04538 CompositeLump* new_lump = split_lump( shell_to_split ); 04539 lump->get_body()->add( new_lump ); 04540 //if (!new_lump->has_hidden_entities()) 04541 // remove_composite( new_lump ); 04542 } 04543 // if (!lump->has_hidden_entities()) 04544 // remove_composite( lump ); 04545 04546 return CUBIT_SUCCESS; 04547 } 04548 04549 //------------------------------------------------------------------------- 04550 // Purpose : Test if a CompositeShell needs to be split, and if 04551 // so, split it and the owning lump. 04552 // 04553 // Special Notes : 04554 // 04555 // Creator : Jason Kraftcheck 04556 // 04557 // Creation Date : 09/27/04 04558 //------------------------------------------------------------------------- 04559 CompositeLump* CompositeEngine::split_lump( CompositeShell* shell_to_split ) 04560 { 04561 int i, j; 04562 04563 // split the shell 04564 CompositeShell* new_shell = split_shell( shell_to_split ); 04565 if (!new_shell) 04566 return shell_to_split->get_lump(); 04567 04568 // Get list of shells to move to new lump 04569 shell_to_split->get_lump()->add( new_shell ); 04570 DLIList<CompositeShell*> shell_list, shells_to_move; 04571 shell_list.append( new_shell ); 04572 shells_to_move.append( new_shell ); 04573 while (shell_list.size()) 04574 { 04575 CompositeShell* shell = shell_list.pop(); 04576 CompositeCoSurf* cosurf = 0; 04577 while ((cosurf = shell->next_co_surf( cosurf ))) 04578 { 04579 CompositeSurface* surf = cosurf->get_surface(); 04580 surf = surf->get_stitch_partner(); 04581 if (!surf) 04582 continue; 04583 04584 CompositeCoSurf* surf_cosurf = 0; 04585 while ((surf_cosurf = surf->next_co_surface( surf_cosurf ))) 04586 { 04587 CompositeShell* surf_shell = surf_cosurf->get_shell(); 04588 if (surf_shell == shell_to_split || 04589 surf_shell->get_lump() != shell_to_split->get_lump() || 04590 shells_to_move.is_in_list( surf_shell )) 04591 continue; 04592 04593 shell_list.append( surf_shell ); 04594 shells_to_move.append( surf_shell ); 04595 } 04596 } 04597 } 04598 04599 // Get list of real lumps defining composite lump that 04600 // are to be moved to the new composite lump 04601 DLIList<Lump*> lumps_to_move; 04602 DLIList<TopologyBridge*> shells, lumps; 04603 for (i = shells_to_move.size(); i--; ) 04604 { 04605 CompositeShell* shell = shells_to_move.get_and_step(); 04606 CompositeCoSurf* cosurf = 0; 04607 while ((cosurf = shell->next_co_surf( cosurf ))) 04608 { 04609 CompositeSurface* surf = cosurf->get_surface(); 04610 for (j = 0; j < surf->num_surfs(); j++) 04611 { 04612 Surface* real_surf = surf->get_surface(j); 04613 real_surf->get_parents_virt( shells ); 04614 while (shells.size()) 04615 { 04616 shells.pop()->get_parents_virt( lumps ); 04617 assert( lumps.size() == 1 ); 04618 TopologyBridge* lump = lumps.pop(); 04619 if (lump->owner() == shell_to_split->get_lump()) 04620 lumps_to_move.append_unique( dynamic_cast<Lump*>(lump) ); 04621 } 04622 } 04623 } 04624 } 04625 04626 if (lumps_to_move.size() == shell_to_split->get_lump()->num_lumps()) 04627 return shell_to_split->get_lump(); 04628 04629 // Split composite lump and move shells to new lump 04630 VGArray<int> vol_indices( lumps_to_move.size() ); 04631 lumps_to_move.reset(); 04632 for (i = lumps_to_move.size(); i--; ) 04633 vol_indices[i] = shell_to_split->get_lump()->index_of( lumps_to_move.next(i) ); 04634 CompositeLump* new_lump = shell_to_split->get_lump()->split( vol_indices ); 04635 new_lump->add( new_shell ); 04636 shells_to_move.reverse(); 04637 while (shells_to_move.size()) 04638 { 04639 CompositeShell* shell = shells_to_move.pop(); 04640 shell_to_split->get_lump()->remove( shell ); 04641 new_lump->add( new_shell ); 04642 } 04643 04644 // Move any hidden entities from old composite to new 04645 HiddenEntitySet* old_set = &shell_to_split->get_lump()->hidden_entities(); 04646 DLIList<TopologyBridge*> surfs; 04647 while (lumps_to_move.size()) 04648 { 04649 Lump* lump = lumps_to_move.pop(); 04650 lump->get_children( shells, true, COMPOSITE_LAYER-1 ); 04651 while (shells.size()) 04652 { 04653 TopologyBridge* shell = shells.pop(); 04654 shell->get_children( surfs, true, COMPOSITE_LAYER ); 04655 while (surfs.size()) 04656 { 04657 CompositeSurface* surf = dynamic_cast<CompositeSurface*>(surfs.pop()); 04658 if (surf->owner() != old_set) 04659 continue; 04660 04661 cme_unhide_surface( surf ); 04662 cme_hide_surface( new_lump->hidden_entities(), surf ); 04663 } 04664 } 04665 } 04666 04667 return new_lump; 04668 } 04669 04670 04671 04672 //------------------------------------------------------------------------- 04673 // Purpose : Recreate composites stored in attributes 04674 // 04675 // Special Notes : 04676 // 04677 // Creator : Jason Kraftcheck 04678 // 04679 // Creation Date : 06/18/02 04680 //------------------------------------------------------------------------- 04681 CubitStatus CompositeEngine::import_geometry( DLIList<TopologyBridge*>& imported_geom ) 04682 { 04683 CubitStatus result = CUBIT_SUCCESS; 04684 int i; 04685 04686 DLIList<BodySM*> bodies; 04687 DLIList<Lump*> lumps, temp_lumps; 04688 DLIList<Surface*> surfaces, temp_surfaces; 04689 DLIList<Curve*> curves, temp_curves; 04690 DLIList<TBPoint*> points, temp_points; 04691 04692 CAST_LIST( imported_geom, bodies, BodySM ); 04693 CAST_LIST( imported_geom, lumps, Lump ); 04694 CAST_LIST( imported_geom, surfaces, Surface ); 04695 CAST_LIST( imported_geom, curves, Curve ); 04696 CAST_LIST( imported_geom, points, TBPoint ); 04697 04698 i = bodies.size() + lumps.size() + surfaces.size() + curves.size() + points.size(); 04699 if( i != imported_geom.size() ) 04700 { 04701 PRINT_WARNING("CompositeEngine: unknown geometry types encountered during import.\n"); 04702 } 04703 04704 // get points from free curves 04705 for( i = curves.size(); i--; ) 04706 { 04707 Curve* ptr = curves.get_and_step(); 04708 temp_points.clean_out(); 04709 ptr->points( temp_points ); 04710 points += temp_points; 04711 } 04712 04713 // get points and curves from free surfaces 04714 for( i = surfaces.size(); i--; ) 04715 { 04716 Surface* ptr = surfaces.get_and_step(); 04717 04718 temp_points.clean_out(); 04719 temp_curves.clean_out(); 04720 04721 ptr->points( temp_points ); 04722 ptr->curves( temp_curves ); 04723 04724 points += temp_points; 04725 curves += temp_curves; 04726 } 04727 04728 // get child geometry from free lumps 04729 // (are there ever any free lumps?) 04730 for( i = lumps.size(); i--; ) 04731 { 04732 Lump* ptr = lumps.get_and_step(); 04733 04734 temp_points.clean_out(); 04735 temp_curves.clean_out(); 04736 temp_surfaces.clean_out(); 04737 04738 ptr->points( temp_points ); 04739 ptr->curves( temp_curves ); 04740 ptr->surfaces( temp_surfaces ); 04741 04742 points += temp_points; 04743 curves += temp_curves; 04744 surfaces += temp_surfaces; 04745 } 04746 04747 // get child geometry from bodies 04748 for( i = bodies.size(); i--; ) 04749 { 04750 BodySM* ptr = bodies.get_and_step(); 04751 04752 temp_points.clean_out(); 04753 temp_curves.clean_out(); 04754 temp_surfaces.clean_out(); 04755 temp_lumps.clean_out(); 04756 04757 ptr->points( temp_points ); 04758 ptr->curves( temp_curves ); 04759 ptr->surfaces( temp_surfaces ); 04760 ptr->lumps( temp_lumps ); 04761 04762 points += temp_points; 04763 curves += temp_curves; 04764 surfaces += temp_surfaces; 04765 lumps += temp_lumps; 04766 } 04767 04768 04769 // assert that lists do not contain duplicates 04770 //assert( (i = points.size(), points.uniquify_ordered(), i == points.size() ) ); 04771 //assert( (i = curves.size(), curves.uniquify_ordered(), i == curves.size() ) ); 04772 points.uniquify_ordered(); // can have duplicates in some non-manifold cases 04773 curves.uniquify_ordered(); // can have duplicates in some non-manifold cases 04774 assert( (i = surfaces.size(), surfaces.uniquify_ordered(), i == surfaces.size()) ); 04775 assert( (i = lumps.size(), lumps.uniquify_ordered(), i == lumps.size() ) ); 04776 04777 if ( CGMApp::instance()->attrib_manager()->auto_actuate_flag(CA_COMPOSITE_VG) && 04778 CGMApp::instance()->attrib_manager()->auto_read_flag(CA_COMPOSITE_VG) ) 04779 { 04780 04781 // Loop through the surfaces and if there is a 04782 // TOPLOGY_BRIDGE_ID attribute get the id and set 04783 // it in the toplogy bridge for the surface. 04784 surfaces.reset(); 04785 for(i=surfaces.size(); i--;) 04786 { 04787 Surface *s = surfaces.get_and_step(); 04788 GeometryEntity *ge = dynamic_cast<GeometryEntity*>(s); 04789 TopologyBridge *tb = dynamic_cast<TopologyBridge*>(s); 04790 if(ge && tb) 04791 { 04792 DLIList<CubitSimpleAttrib> list; 04793 ge->get_simple_attribute("TOPOLOGY_BRIDGE_ID",list); 04794 list.reset(); 04795 for(int j = list.size(); j--;) 04796 { 04797 const CubitSimpleAttrib& attrib = list.get_and_step(); 04798 assert(attrib.int_data_list().size() == 1); 04799 int id = attrib.int_data_list()[0]; 04800 ge->set_saved_id(id); 04801 04802 std::vector<CubitString> names = attrib.string_data_list(); 04803 if(!names.empty()) 04804 names.erase(names.begin()); 04805 04806 ge->set_saved_names( names ); 04807 04808 tb->remove_simple_attribute_virt(attrib); 04809 } 04810 } 04811 } 04812 04813 // Need to do curves here too. 04814 curves.reset(); 04815 for(i=curves.size(); i--;) 04816 { 04817 Curve *c = curves.get_and_step(); 04818 GeometryEntity *ge = dynamic_cast<GeometryEntity*>(c); 04819 TopologyBridge *tb = dynamic_cast<TopologyBridge*>(c); 04820 if(ge && tb) 04821 { 04822 DLIList<CubitSimpleAttrib> list; 04823 ge->get_simple_attribute("TOPOLOGY_BRIDGE_ID",list); 04824 list.reset(); 04825 for(int j = list.size(); j--;) 04826 { 04827 const CubitSimpleAttrib& attrib = list.get_and_step(); 04828 assert(attrib.int_data_list().size() == 1); 04829 int id = attrib.int_data_list()[0]; 04830 ge->set_saved_id(id); 04831 04832 std::vector<CubitString> names = attrib.string_data_list(); 04833 if(!names.empty()) 04834 names.erase(names.begin()); 04835 ge->set_saved_names( names ); 04836 04837 tb->remove_simple_attribute_virt(attrib); 04838 } 04839 } 04840 } 04841 04842 // create composites top-down 04843 if( !create_composites( bodies ) ) result = CUBIT_FAILURE; 04844 if( !create_composites( surfaces ) ) result = CUBIT_FAILURE; 04845 if( !create_composites( curves ) ) result = CUBIT_FAILURE; 04846 if( !create_composites( points ) ) result = CUBIT_FAILURE; 04847 04848 04849 for( i = bodies.size(); i--; ) 04850 { 04851 BodySM* ptr = bodies.get_and_step(); 04852 04853 temp_curves.clean_out(); 04854 temp_surfaces.clean_out(); 04855 04856 ptr->curves( temp_curves ); 04857 ptr->surfaces( temp_surfaces ); 04858 04859 //for each curve or surface, if it is not a composite, 04860 //and has a COMPOSIT_DATA_ATTRIB_NAME, 04861 //which is an ENTITY_NAME, convert it into an ENTITY_NAME attribute 04862 04863 for( int k=temp_curves.size(); k--; ) 04864 { 04865 Curve *tmp_curve = temp_curves.get_and_step(); 04866 04867 DLIList<CubitSimpleAttrib> list; 04868 tmp_curve->get_simple_attribute("COMPOSITE_ATTRIB",list); 04869 for( int j = list.size(); j--; ) 04870 { 04871 CubitSimpleAttrib tmp_attrib = list.get_and_step(); 04872 std::vector<CubitString> string_list = tmp_attrib.string_data_list(); 04873 if( string_list[1] == "ENTITY_NAME" && !dynamic_cast<CompositeCurve*>( tmp_curve ) ) 04874 { 04875 //convert the attribute into an ENTITY_NAME attribute 04876 tmp_curve->remove_simple_attribute_virt( tmp_attrib ); 04877 tmp_attrib.string_data_list().erase( tmp_attrib.string_data_list().begin() ); 04878 tmp_curve->append_simple_attribute_virt( tmp_attrib ); 04879 } 04880 } 04881 } 04882 04883 for( int k=temp_surfaces.size(); k--; ) 04884 { 04885 Surface *tmp_surf = temp_surfaces.get_and_step(); 04886 04887 DLIList<CubitSimpleAttrib> list; 04888 tmp_surf->get_simple_attribute("COMPOSITE_ATTRIB",list); 04889 for( int j = list.size(); j--; ) 04890 { 04891 CubitSimpleAttrib tmp_attrib = list.get_and_step(); 04892 std::vector<CubitString> string_list = tmp_attrib.string_data_list(); 04893 if( string_list[1] == "ENTITY_NAME" && !dynamic_cast<CompositeSurface*>( tmp_surf ) ) 04894 { 04895 //convert the attribute into an ENTITY_NAME attribute 04896 tmp_surf->remove_simple_attribute_virt( tmp_attrib ); 04897 tmp_attrib.string_data_list().erase( tmp_attrib.string_data_list().begin() ); 04898 tmp_surf->append_simple_attribute_virt( tmp_attrib ); 04899 } 04900 } 04901 } 04902 } 04903 } 04904 04905 for ( i = bodies.size(); i--; ) 04906 strip_attributes( bodies.get_and_step() ); 04907 for ( i = surfaces.size(); i--; ) 04908 strip_attributes( surfaces.get_and_step() ); 04909 for ( i = curves.size(); i--; ) 04910 strip_attributes( curves.get_and_step() ); 04911 for ( i = points.size(); i--; ) 04912 strip_attributes( points.get_and_step() ); 04913 04914 // update imported_geom list to contain composites rather than 04915 // entities used to create the composites 04916 for( i = imported_geom.size(); i--; ) 04917 { 04918 TopologyBridge* bridge = imported_geom.step_and_get(); 04919 TopologyBridge* virt = dynamic_cast<TopologyBridge*>(bridge->owner()); 04920 if( virt ) 04921 imported_geom.change_to( virt ); 04922 } 04923 04924 /* DON'T DO THIS. IT CHANGES THE ORDER OF THE IMPORT LIST, 04925 CAUSING IDS TO CHANGE. FURTHER, IT RANDOMIZES THE IDS. 04926 04927 // composites were put in the list once for each underlying 04928 // entity. need to remove the duplicates. 04929 imported_geom.uniquify_unordered(); 04930 */ 04931 // that's all folks 04932 return result; 04933 } 04934 04935 bool CompositeEngine::is_composite(TBOwner *bridge_owner) 04936 { 04937 bool ret = false; 04938 if(bridge_owner) 04939 { 04940 if(dynamic_cast<CompositeBody*>(bridge_owner) || 04941 dynamic_cast<CompositeLump*>(bridge_owner) || 04942 dynamic_cast<CompositeSurface*>(bridge_owner) || 04943 dynamic_cast<CompositeCurve*>(bridge_owner) || 04944 dynamic_cast<CompositeCoEdge*>(bridge_owner) || 04945 dynamic_cast<CompositePoint*>(bridge_owner)) 04946 { 04947 ret = true; 04948 } 04949 } 04950 return ret; 04951 } 04952 04953 bool CompositeEngine::is_composite(TopologyBridge *bridge) 04954 { 04955 bool ret = false; 04956 if(bridge) 04957 { 04958 if(dynamic_cast<CompositeBody*>(bridge) || 04959 dynamic_cast<CompositeLump*>(bridge) || 04960 dynamic_cast<CompositeSurface*>(bridge) || 04961 dynamic_cast<CompositeCurve*>(bridge) || 04962 dynamic_cast<CompositeCoEdge*>(bridge) || 04963 dynamic_cast<CompositePoint*>(bridge)) 04964 { 04965 ret = true; 04966 } 04967 } 04968 return ret; 04969 } 04970 04971 bool CompositeEngine::is_partition(TBOwner *bridge_owner) 04972 { 04973 return false; 04974 } 04975 04976 void CompositeEngine::remove_attributes( DLIList<TopologyBridge*> &bridge_list ) 04977 { 04978 //remove attributes off of underlying/hidden entities 04979 DLIList<Curve*> curve_list, temp_curves; 04980 DLIList<Surface*> surface_list, temp_surfaces; 04981 DLIList<Lump*> lump_list; 04982 DLIList<BodySM*> body_list; 04983 04984 CAST_LIST( bridge_list, curve_list, Curve ); 04985 CAST_LIST( bridge_list, surface_list, Surface ); 04986 CAST_LIST( bridge_list, lump_list, Lump ); 04987 CAST_LIST( bridge_list, body_list, BodySM ); 04988 04989 int i; 04990 for( i = surface_list.size(); i--; ) 04991 { 04992 temp_curves.clean_out(); 04993 surface_list.get_and_step()->curves( temp_curves ); 04994 curve_list += temp_curves; 04995 } 04996 04997 for( i = lump_list.size(); i--; ) 04998 { 04999 Lump* lump = lump_list.get_and_step(); 05000 05001 temp_curves.clean_out(); 05002 lump->curves( temp_curves ); 05003 curve_list += temp_curves; 05004 05005 temp_surfaces.clean_out(); 05006 lump->surfaces( temp_surfaces ); 05007 surface_list += temp_surfaces; 05008 } 05009 for( i = body_list.size(); i--; ) 05010 { 05011 BodySM* body = body_list.get_and_step(); 05012 05013 temp_curves.clean_out(); 05014 body->curves( temp_curves ); 05015 curve_list += temp_curves; 05016 05017 temp_surfaces.clean_out(); 05018 body->surfaces( temp_surfaces ); 05019 surface_list += temp_surfaces; 05020 } 05021 05022 // DLIList<CompositeCurve*> ccurve_list; 05023 // DLIList<CompositeSurface*> csurf_list; 05024 05025 // CAST_LIST( curve_list, ccurve_list, CompositeCurve ); 05026 // CAST_LIST( surface_list, csurf_list, CompositeSurface ); 05027 05028 // ccurve_list.uniquify_unordered(); 05029 // csurf_list.uniquify_unordered(); 05030 curve_list.uniquify_ordered(); 05031 surface_list.uniquify_ordered(); 05032 05033 int j,k; 05034 for( i = curve_list.size(); i--; ) 05035 { 05036 Curve *tmp_curve = curve_list.get_and_step(); 05037 strip_attributes(tmp_curve); 05038 CompositeCurve* tmp_comp_curve = dynamic_cast<CompositeCurve*>(tmp_curve); 05039 if(tmp_comp_curve) 05040 { 05041 for( j = 0; j < tmp_comp_curve->num_curves(); j++ ) 05042 { 05043 strip_attributes( tmp_comp_curve->get_curve(j) ); 05044 05045 //remove attributes off underlying points too 05046 DLIList<TBPoint*> hidden_points; 05047 tmp_comp_curve->get_hidden_points( hidden_points ); 05048 for( k=hidden_points.size(); k--; ) 05049 strip_attributes( hidden_points.get_and_step() ); 05050 } 05051 } 05052 } 05053 for( i = surface_list.size(); i--; ) 05054 { 05055 Surface *tmp_surf = surface_list.get_and_step(); 05056 strip_attributes(tmp_surf); 05057 CompositeSurface *tmp_comp_surf = dynamic_cast<CompositeSurface*>(tmp_surf); 05058 if(tmp_comp_surf) 05059 { 05060 for( int j = 0; j < tmp_comp_surf->num_surfs(); j++ ) 05061 strip_attributes( tmp_comp_surf->get_surface(j) ); 05062 } 05063 } 05064 05065 //remove attrigutes off of bridges passed in 05066 for( i=bridge_list.size(); i--; ) 05067 strip_attributes( bridge_list.get_and_step() ); 05068 } 05069 05070 void CompositeEngine::remove_attributes_from_unmodifed_virtual( DLIList<TopologyBridge*> &bridge_list ) 05071 { 05072 //remove attributes off of underlying/hidden entities 05073 DLIList<Curve*> curve_list, temp_curves; 05074 DLIList<Surface*> surface_list, temp_surfaces; 05075 DLIList<Lump*> lump_list; 05076 DLIList<BodySM*> body_list; 05077 05078 CAST_LIST( bridge_list, curve_list, Curve ); 05079 CAST_LIST( bridge_list, surface_list, Surface ); 05080 CAST_LIST( bridge_list, lump_list, Lump ); 05081 CAST_LIST( bridge_list, body_list, BodySM ); 05082 05083 int i; 05084 for( i = surface_list.size(); i--; ) 05085 { 05086 temp_curves.clean_out(); 05087 surface_list.get_and_step()->curves( temp_curves ); 05088 curve_list += temp_curves; 05089 } 05090 05091 for( i = lump_list.size(); i--; ) 05092 { 05093 Lump* lump = lump_list.get_and_step(); 05094 05095 temp_curves.clean_out(); 05096 lump->curves( temp_curves ); 05097 curve_list += temp_curves; 05098 05099 temp_surfaces.clean_out(); 05100 lump->surfaces( temp_surfaces ); 05101 surface_list += temp_surfaces; 05102 } 05103 for( i = body_list.size(); i--; ) 05104 { 05105 BodySM* body = body_list.get_and_step(); 05106 05107 temp_curves.clean_out(); 05108 body->curves( temp_curves ); 05109 curve_list += temp_curves; 05110 05111 temp_surfaces.clean_out(); 05112 body->surfaces( temp_surfaces ); 05113 surface_list += temp_surfaces; 05114 } 05115 05116 DLIList<CompositeCurve*> ccurve_list; 05117 DLIList<CompositeSurface*> csurf_list; 05118 05119 CAST_LIST( curve_list, ccurve_list, CompositeCurve ); 05120 CAST_LIST( surface_list, csurf_list, CompositeSurface ); 05121 05122 ccurve_list.uniquify_ordered(); 05123 csurf_list.uniquify_ordered(); 05124 05125 int k; 05126 for( i = ccurve_list.size(); i--; ) 05127 { 05128 CompositeCurve* tmp_comp_curve = ccurve_list.get_and_step(); 05129 /* 05130 for( j = 0; j < tmp_comp_curve->num_curves(); j++ ) 05131 { 05132 // strip_attributes( tmp_comp_curve->get_curve(j) ); 05133 05134 //remove attributes off underlying points too 05135 } 05136 */ 05137 DLIList<TBPoint*> hidden_points; 05138 tmp_comp_curve->get_hidden_points( hidden_points ); 05139 for( k=hidden_points.size(); k--; ) 05140 strip_attributes( hidden_points.get_and_step() ); 05141 } 05142 for( i = csurf_list.size(); i--; ) 05143 { 05144 CompositeSurface *tmp_comp_surf = csurf_list.get_and_step(); 05145 /* 05146 for( int j = 0; j < tmp_comp_surf->num_surfs(); j++ ) 05147 strip_attributes( tmp_comp_surf->get_surface(j) ); 05148 */ 05149 DLIList<Curve*> hidden_curves; 05150 tmp_comp_surf->get_hidden_curves( hidden_curves ); 05151 for( k=hidden_curves.size(); k--; ) 05152 strip_attributes( hidden_curves.get_and_step() ); 05153 } 05154 05155 //remove attrigutes off of bridges passed in 05156 /* 05157 for( i=bridge_list.size(); i--; ) 05158 strip_attributes( bridge_list.get_and_step() ); 05159 */ 05160 } 05161 05162 void CompositeEngine::strip_attributes( TopologyBridge* bridge ) 05163 { 05164 const char* const attrib_names[] = { "COMPOSITE_GEOM", 05165 "COMPOSITE_STITCH", 05166 "COMPOSITE_SENSE", 05167 "COMPOSITE_ATTRIB", 05168 "COMPOSITE_NULLGEOM", 05169 "TOPOLOGY_BRIDGE_ID", 05170 0 }; 05171 05172 DLIList<CubitSimpleAttrib> list; 05173 for( int i = 0; attrib_names[i]; i++ ) 05174 { 05175 bridge->get_simple_attribute( attrib_names[i], list ); 05176 while( list.size() ) 05177 { 05178 bridge->remove_simple_attribute_virt(list.pop()); 05179 } 05180 } 05181 } 05182 05183 05184 //------------------------------------------------------------------------- 05185 // Purpose : Retreive the CSA with the specified name if it exists 05186 // 05187 // Special Notes : 05188 // 05189 // Creator : Jason Kraftcheck 05190 // 05191 // Creation Date : 06/18/02 05192 //------------------------------------------------------------------------- 05193 CubitSimpleAttrib 05194 CompositeEngine::find_attribute_by_name( TopologyBridge* bridge, 05195 const CubitString name ) 05196 { 05197 CubitSimpleAttrib result; 05198 DLIList<CubitSimpleAttrib> attrib_list; 05199 bridge->get_simple_attribute( name, attrib_list ); 05200 attrib_list.reset(); 05201 if ( attrib_list.size() ) 05202 result = attrib_list.extract(); 05203 05204 return result; 05205 } 05206 05207 //------------------------------------------------------------------------- 05208 // Purpose : Create composite surfaces 05209 // 05210 // Special Notes : 05211 // 05212 // Creator : Jason Kraftcheck 05213 // 05214 // Creation Date : 06/18/02 05215 //------------------------------------------------------------------------- 05216 CubitStatus CompositeEngine::create_composites( DLIList<Curve*>& list ) 05217 { 05218 CubitStatus result = CUBIT_FAILURE; 05219 05220 for( int i = list.size(); i--; ) 05221 { 05222 Curve* curve = list.get_and_step(); 05223 CompositeCurve* ccurve; 05224 ccurve = dynamic_cast<CompositeCurve*>(curve->owner()); 05225 if( ccurve ) 05226 curve = ccurve; 05227 CubitSimpleAttrib attrib = find_attribute_by_name( curve, "COMPOSITE_GEOM" ); 05228 if( !attrib.isEmpty() ) 05229 { 05230 curve->remove_simple_attribute_virt( attrib ); 05231 05232 /* 05233 Curve* stitch_partner = 0; 05234 if( attrib->int_data_list()->size() ) 05235 { 05236 assert(attrib->int_data_list()->size() == 1 ); 05237 attrib->int_data_list()->reset(); 05238 int stitch_partner_id = *attrib->int_data_list()->get(); 05239 TopologyBridge* bridge = stitchMap[stitch_partner_id]; 05240 if( !bridge ) 05241 { 05242 stitchMap[stitch_partner_id] = curve; 05243 continue; 05244 } 05245 05246 stitch_partner = dynamic_cast<Curve*>(bridge); 05247 assert( !!stitch_partner ); 05248 } 05249 05250 CompositeCurve* ccurve; 05251 ccurve = dynamic_cast<CompositeCurve*>(curve->owner()); 05252 if( ccurve ) 05253 curve = ccurve; 05254 if( stitch_partner ) 05255 { 05256 ccurve = dynamic_cast<CompositeCurve*>(stitch_partner->owner()); 05257 if( ccurve ) 05258 stitch_partner = ccurve; 05259 } 05260 05261 CompositeSurface* surf = remove_curve( curve, stitch_partner ); 05262 if( !surf ) 05263 { 05264 PRINT_ERROR("Error creating composite surface. Could not remove curve.\n"); 05265 result = CUBIT_FAILURE; 05266 } 05267 */ 05268 CompositeSurface* surf = remove_curve( curve ); 05269 if( !surf ) 05270 { 05271 PRINT_ERROR("Error creating composite surface. Could not remove curve.\n"); 05272 result = CUBIT_FAILURE; 05273 } 05274 else 05275 { 05276 // Tell the composite surface which surfaces to ignore during 05277 // evaluation. 05278 for(int j=0; j<surf->num_surfs(); j++) 05279 { 05280 Surface *srf = surf->get_surface(j); 05281 CubitSimpleAttrib ignore_attrib = find_attribute_by_name( srf, "COMPOSITE_IGNORE" ); 05282 if( !ignore_attrib.isEmpty() ) 05283 { 05284 surf->ignore_surface(srf); 05285 srf->remove_simple_attribute_virt( ignore_attrib ); 05286 } 05287 } 05288 surf->read_attributes(); 05289 } 05290 } 05291 } 05292 return result; 05293 } 05294 05295 05296 //------------------------------------------------------------------------- 05297 // Purpose : Create composite curves 05298 // 05299 // Special Notes : 05300 // 05301 // Creator : Jason Kraftcheck 05302 // 05303 // Creation Date : 06/18/02 05304 //------------------------------------------------------------------------- 05305 CubitStatus CompositeEngine::create_composites( DLIList<TBPoint*>& list ) 05306 { 05307 CubitStatus result = CUBIT_FAILURE; 05308 05309 // Restore composite curves. 05310 int i; 05311 for( i = list.size(); i--; ) 05312 { 05313 TBPoint* point = list.get_and_step(); 05314 CompositePoint* cpoint; 05315 cpoint = dynamic_cast<CompositePoint*>(point->owner()); 05316 if( cpoint ) 05317 point = cpoint; 05318 CubitSimpleAttrib attrib = find_attribute_by_name( point, "COMPOSITE_GEOM" ); 05319 if( !attrib.isEmpty() ) 05320 { 05321 point->remove_simple_attribute_virt( attrib ); 05322 // Make sure we have a situation where we can perform 05323 // the composite before trying. 05324 DLIList<TopologyBridge*> attached_curves; 05325 point->get_parents_virt(attached_curves); 05326 if(attached_curves.size() == 2 && 05327 attached_curves[0] != attached_curves[1]) 05328 { 05329 CompositeCurve* curve = remove_point(point); 05330 if( !curve ) 05331 { 05332 PRINT_ERROR("Error creating composite curve. Could not remove point.\n"); 05333 result = CUBIT_FAILURE; 05334 } 05335 else 05336 { 05337 curve->read_attributes(); 05338 } 05339 } 05340 } 05341 } 05342 05343 // Restore point curves 05344 for( i = list.size(); i--; ) 05345 { 05346 TBPoint* point = list.get_and_step(); 05347 CompositePoint* cpoint; 05348 cpoint = dynamic_cast<CompositePoint*>(point->owner()); 05349 if( cpoint ) 05350 point = cpoint; 05351 CubitSimpleAttrib attrib = find_attribute_by_name( point, "COMPOSITE_NULLGEOM" ); 05352 if( !attrib.isEmpty() ) 05353 { 05354 point->remove_simple_attribute_virt( attrib ); 05355 05356 CompositeCurve* curve = restore_point_in_surface( point ); 05357 if( !curve ) 05358 { 05359 PRINT_ERROR("Error creating composite curve. Could not rrestore point-curve.\n"); 05360 result = CUBIT_FAILURE; 05361 } 05362 else 05363 { 05364 curve->read_attributes(); 05365 } 05366 } 05367 } 05368 05369 return result; 05370 } 05371 05372 05373 //------------------------------------------------------------------------- 05374 // Purpose : Create composite lumps 05375 // 05376 // Special Notes : 05377 // 05378 // Creator : Jason Kraftcheck 05379 // 05380 // Creation Date : 06/18/02 05381 //------------------------------------------------------------------------- 05382 CubitStatus CompositeEngine::create_composites( DLIList<Surface*>& ) 05383 { return CUBIT_SUCCESS; } 05384 05385 //------------------------------------------------------------------------- 05386 // Purpose : Create composite bodies 05387 // 05388 // Special Notes : 05389 // 05390 // Creator : Jason Kraftcheck 05391 // 05392 // Creation Date : 06/18/02 05393 //------------------------------------------------------------------------- 05394 CubitStatus CompositeEngine::create_composites( DLIList<BodySM*>& ) 05395 { 05396 return CUBIT_SUCCESS; 05397 } 05398 05399 //------------------------------------------------------------------------- 05400 // Purpose : Save composite geometry 05401 // 05402 // Special Notes : 05403 // 05404 // Creator : Jason Kraftcheck 05405 // 05406 // Creation Date : 06/18/02 05407 //------------------------------------------------------------------------- 05408 CubitStatus CompositeEngine::export_geometry( DLIList<TopologyBridge*>& list ) 05409 { 05410 int i; 05411 CubitStatus result = CUBIT_SUCCESS; 05412 05413 if ( CGMApp::instance()->attrib_manager()->auto_update_flag(CA_COMPOSITE_VG) && 05414 CGMApp::instance()->attrib_manager()->auto_write_flag(CA_COMPOSITE_VG) ) 05415 { 05416 05417 DLIList<Curve*> curve_list, temp_curves; 05418 DLIList<Surface*> surface_list, temp_surfaces; 05419 DLIList<Lump*> lump_list, temp_lumps; 05420 DLIList<BodySM*> body_list; 05421 05422 CAST_LIST( list, curve_list, Curve ); 05423 CAST_LIST( list, surface_list, Surface ); 05424 CAST_LIST( list, lump_list, Lump ); 05425 CAST_LIST( list, body_list, BodySM ); 05426 05427 for( i = surface_list.size(); i--; ) 05428 { 05429 Surface* surf = surface_list.get_and_step(); 05430 temp_curves.clean_out(); 05431 surf->curves( temp_curves ); 05432 curve_list += temp_curves; 05433 } 05434 for( i = lump_list.size(); i--; ) 05435 { 05436 Lump* lump = lump_list.get_and_step(); 05437 05438 temp_curves.clean_out(); 05439 lump->curves( temp_curves ); 05440 curve_list += temp_curves; 05441 05442 temp_surfaces.clean_out(); 05443 lump->surfaces( temp_surfaces ); 05444 surface_list += temp_surfaces; 05445 } 05446 for( i = body_list.size(); i--; ) 05447 { 05448 BodySM* body = body_list.get_and_step(); 05449 05450 temp_curves.clean_out(); 05451 body->curves( temp_curves ); 05452 curve_list += temp_curves; 05453 05454 temp_surfaces.clean_out(); 05455 body->surfaces( temp_surfaces ); 05456 surface_list += temp_surfaces; 05457 05458 temp_lumps.clean_out(); 05459 body->lumps( temp_lumps ); 05460 lump_list += temp_lumps; 05461 } 05462 05463 DLIList<CompositeCurve*> ccurve_list; 05464 DLIList<CompositeSurface*> csurf_list; 05465 DLIList<CompositeLump*> clump_list; 05466 DLIList<CompositeBody*> cbody_list; 05467 05468 CAST_LIST( curve_list, ccurve_list, CompositeCurve ); 05469 CAST_LIST( surface_list, csurf_list, CompositeSurface ); 05470 // CAST_LIST( lump_list, clump_list, CompositeLump ); 05471 // CAST_LIST( body_list, cbody_list, CompositeBody ); 05472 05473 ccurve_list.uniquify_ordered(); 05474 csurf_list.uniquify_ordered(); 05475 05476 05477 // Add an attribute to each topology bridge specifying what its id is. Upon restoring 05478 // the file these attributes will be read so that the topology id can be stored with the 05479 // topology bridge. Normally, the ids would get set when creating the associated RefEntity 05480 // and the topology bridge id would be set to be that of the RefEntity. However, for the 05481 // underlying entities of a composite RefEntities are not created so the ids never get 05482 // set when restoring. Thus we are doing it manually here. Only doing curves and 05483 // surfaces right now. 05484 csurf_list.reset(); 05485 for(i=csurf_list.size(); i--;) 05486 { 05487 CompositeSurface *cs = csurf_list.get_and_step(); 05488 int number_surfs = cs->num_surfs(); 05489 for(int j=0; j<number_surfs; ++j) 05490 { 05491 Surface *s = cs->get_surface(j); 05492 GeometryEntity *ge = dynamic_cast<GeometryEntity*>(s); 05493 TopologyBridge *tb = dynamic_cast<TopologyBridge*>(s); 05494 if(ge && tb) 05495 { 05496 std::vector<int> int_list; 05497 int_list.push_back(ge->get_saved_id() ); 05498 05499 //save out the names 05500 std::vector<CubitString> names; 05501 ge->get_saved_names( names ); 05502 names.insert(names.begin(), CubitString("TOPOLOGY_BRIDGE_ID")); 05503 CubitSimpleAttrib geom_attrib( &names, 0, &int_list ); 05504 append_attrib(tb, geom_attrib); 05505 } 05506 } 05507 } 05508 05509 ccurve_list.reset(); 05510 for(i=ccurve_list.size(); i--;) 05511 { 05512 CompositeCurve *cc = ccurve_list.get_and_step(); 05513 int number_curves = cc->num_curves(); 05514 for(int j=0; j<number_curves; ++j) 05515 { 05516 Curve *c = cc->get_curve(j); 05517 GeometryEntity *ge = dynamic_cast<GeometryEntity*>(c); 05518 TopologyBridge *tb = dynamic_cast<TopologyBridge*>(c); 05519 if(ge && tb) 05520 { 05521 std::vector<int> int_list; 05522 int_list.push_back( ge->get_saved_id() ); 05523 05524 //save out the names 05525 std::vector<CubitString> names; 05526 ge->get_saved_names( names ); 05527 names.insert(names.begin(), CubitString("TOPOLOGY_BRIDGE_ID")); 05528 05529 CubitSimpleAttrib geom_attrib( &names, 0, &int_list ); 05530 append_attrib(tb, geom_attrib); 05531 } 05532 } 05533 } 05534 05535 for( i = ccurve_list.size(); i--; ) 05536 save( ccurve_list.get_and_step() ); 05537 for( i = csurf_list.size(); i--; ) 05538 save( csurf_list.get_and_step() ); 05539 for( i = clump_list.size(); i--; ) 05540 save( clump_list.get_and_step() ); 05541 for( i = cbody_list.size(); i--; ) 05542 save( cbody_list.get_and_step() ); 05543 } 05544 05545 list.reset(); 05546 DLIList<TopologyBridge*> underlying; 05547 for( i = list.size(); i--; ) 05548 { 05549 TopologyBridge* ptr = list.step_and_get(); 05550 underlying.clean_out(); 05551 if( CompositeCurve* curve = dynamic_cast<CompositeCurve*>(ptr) ) 05552 for( int j = 0; j < curve->num_curves(); j++ ) 05553 underlying.append( curve->get_curve(j) ); 05554 else if( CompositeSurface* surf = dynamic_cast<CompositeSurface*>(ptr) ) 05555 for( int j = 0; j < surf->num_surfs(); j++ ) 05556 underlying.append( surf->get_surface(j) ); 05557 /* 05558 else if( CompositeLump* lump = dynamic_cast<CompositeLump*>)(ptr) ) 05559 for( int j = 0; j < lump->num_entities(); j++ ) 05560 underlying.append( lump->lump(j) ); 05561 else if( CompositeBody* body = dynamic_cast<CompositeBody*>)(ptr) ) 05562 for( int j = 0; j < body->num_entities(); j++ ) 05563 underlying.append( body->body(j) ); 05564 */ 05565 if( underlying.size() ) 05566 { 05567 list.change_to( underlying.pop() ); 05568 list += underlying; 05569 } 05570 } 05571 05572 return result; 05573 } 05574 05575 05576 void CompositeEngine::append_attrib( TopologyBridge* tb, 05577 const CubitSimpleAttrib& csa ) 05578 { 05579 CubitSimpleAttrib old = find_attribute_by_name( tb, 05580 csa.character_type() ); 05581 if( !old.isEmpty() ) 05582 { 05583 tb->remove_simple_attribute_virt( old ); 05584 } 05585 tb->append_simple_attribute_virt( csa ); 05586 } 05587 05588 05589 CubitStatus CompositeEngine::save( CompositePoint* point ) 05590 { 05591 DLIList<CompositePoint*> points; 05592 point->get_stitched( points ); 05593 if( points.size() > 1 ) 05594 { 05595 CubitString name("COMPOSITE_STITCH"); 05596 std::vector<CubitString> string_list; 05597 string_list.push_back(name); 05598 CubitSimpleAttrib geom_attrib( &string_list, 0, 0 ); 05599 int uid = TDUniqueId::generate_unique_id(); 05600 geom_attrib.int_data_list().push_back( uid ); 05601 05602 for( int i = points.size(); i--; ) 05603 append_attrib( points.step_and_get()->get_point(), geom_attrib ); 05604 } 05605 return CUBIT_SUCCESS; 05606 } 05607 05608 05609 CubitStatus CompositeEngine::save( CompositeCurve* curve ) 05610 { 05611 DLIList<TBPoint*> hidden_points; 05612 std::vector<CubitString> string_list; 05613 05614 if (curve->num_curves() == 0) // point-curve 05615 { 05616 assert(hidden_points.size() == 0); 05617 CubitString ptname("COMPOSITE_NULLGEOM"); 05618 string_list.clear(); 05619 string_list.push_back( ptname ); 05620 CubitSimpleAttrib null_geom_attrib( &string_list, 0, 0 ); 05621 CompositePoint* pt = curve->start_point(); 05622 assert(curve->end_point() == pt); 05623 append_attrib( pt, null_geom_attrib ); 05624 curve->write_attributes(); 05625 return CUBIT_SUCCESS; 05626 } 05627 05628 ; 05629 string_list.push_back( CubitString("COMPOSITE_GEOM") ); 05630 CubitSimpleAttrib geom_attrib( &string_list, 0, 0 ); 05631 05632 int i; 05633 05634 curve->write_attributes(); 05635 curve->get_hidden_points( hidden_points ); 05636 for( i = hidden_points.size(); i--; ) 05637 { 05638 TBPoint* point = hidden_points.get_and_step(); 05639 if( CompositePoint* cpoint = dynamic_cast<CompositePoint*>(point) ) 05640 save(cpoint); 05641 05642 append_attrib( point, geom_attrib ); 05643 } 05644 05645 05646 if( curve->is_stitched() && curve == curve->primary_stitched_curve() ) 05647 { 05648 int stitch_uid = TDUniqueId::generate_unique_id(); 05649 DLIList<CompositeCurve*> curve_list; 05650 curve->get_stitched( curve_list ); 05651 05652 string_list[0] = "COMPOSITE_STITCH"; 05653 CubitSimpleAttrib stitch_attrib( &string_list, 0, 0 ); 05654 stitch_attrib.int_data_list().push_back(stitch_uid); 05655 for( i = curve_list.size(); i--; ) 05656 append_attrib( curve_list.step_and_get(), stitch_attrib ); 05657 stitch_attrib.int_data_list().clear(); 05658 05659 if( curve_list.move_to( curve ) ) 05660 curve_list.extract(); 05661 05662 for( i = curve_list.size(); i--; ) 05663 save( curve_list.step_and_get() ); 05664 } 05665 05666 05667 string_list[0] = "COMPOSITE_SENSE"; 05668 CubitSimpleAttrib sense_attrib( &string_list, 0, 0 ); 05669 05670 for( i = 0; i < curve->num_curves(); i++ ) 05671 { 05672 CubitSimpleAttrib old = find_attribute_by_name( curve->get_curve(i), "COMPOSITE_SENSE" ); 05673 if( !old.isEmpty() ) 05674 { 05675 if( curve->get_sense(i) == CUBIT_FORWARD ) 05676 curve->get_curve(i)->remove_simple_attribute_virt( old ); 05677 } 05678 else if( curve->get_sense(i) == CUBIT_REVERSED ) 05679 { 05680 curve->get_curve(i)->append_simple_attribute_virt( sense_attrib ); 05681 } 05682 } 05683 05684 return CUBIT_SUCCESS; 05685 } 05686 05687 05688 CubitStatus CompositeEngine::save( CompositeSurface* surf ) 05689 { 05690 DLIList<Curve*> comp_curves; 05691 surf->hidden_entities().hidden_curves( comp_curves ); 05692 surf->write_attributes(); 05693 05694 std::vector<CubitString> string_list; 05695 string_list.push_back( CubitString("COMPOSITE_GEOM") ); 05696 CubitSimpleAttrib geom_attrib( &string_list, 0, 0 ); 05697 05698 int i, j; 05699 05700 for( i = comp_curves.size(); i--; ) 05701 { 05702 CompositeCurve* ccurve = 05703 dynamic_cast<CompositeCurve*>(comp_curves.get_and_step()); 05704 assert(ccurve!= NULL ); 05705 05706 for( j = 0; j < ccurve->num_curves(); j++ ) 05707 { 05708 Curve* tb = ccurve->get_curve(j); 05709 append_attrib( tb, geom_attrib ); 05710 } 05711 } 05712 05713 05714 if( surf->get_stitch_partner() ) 05715 { 05716 CubitSimpleAttrib old = 05717 find_attribute_by_name( surf->get_stitch_partner(), "COMPOSITE_STITCH" ); 05718 if( !old.isEmpty() ) 05719 { 05720 append_attrib( surf, old ); 05721 } 05722 else 05723 { 05724 int stitch_uid = TDUniqueId::generate_unique_id(); 05725 string_list[0] = "COMPOSITE_STITCH"; 05726 CubitSimpleAttrib stitch_attrib( &string_list, 0, 0); 05727 stitch_attrib.int_data_list().push_back( stitch_uid ); 05728 append_attrib( surf, stitch_attrib ); 05729 stitch_attrib.int_data_list().clear(); 05730 } 05731 } 05732 05733 05734 string_list[0] = "COMPOSITE_SENSE"; 05735 CubitSimpleAttrib sense_attrib( &string_list, 0, 0 ); 05736 05737 for( i = 0; i < surf->num_surfs(); i++ ) 05738 { 05739 CubitSimpleAttrib old = find_attribute_by_name( surf->get_surface(i), "COMPOSITE_SENSE" ); 05740 if( !old.isEmpty() ) 05741 { 05742 if( surf->get_sense(i) == CUBIT_FORWARD ) 05743 surf->get_surface(i)->remove_simple_attribute_virt( old ); 05744 } 05745 else if( surf->get_sense(i) == CUBIT_REVERSED ) 05746 { 05747 surf->get_surface(i)->append_simple_attribute_virt( sense_attrib ); 05748 } 05749 } 05750 05751 string_list[0] = "COMPOSITE_IGNORE"; 05752 CubitSimpleAttrib ignore_attrib( &string_list, 0, 0 ); 05753 05754 DLIList<Surface*> srfs; 05755 surf->get_ignored_surfs(srfs); 05756 for( i = 0; i < surf->num_surfs(); i++ ) 05757 { 05758 Surface *srf = surf->get_surface(i); 05759 if(srfs.is_in_list(srf)) 05760 srf->append_simple_attribute_virt(ignore_attrib); 05761 } 05762 05763 05764 return CUBIT_SUCCESS; 05765 } 05766 05767 CubitStatus CompositeEngine::save( CompositeLump* lump ) 05768 { 05769 DLIList<Surface*> comp_surfs; 05770 lump->hidden_entities().hidden_surfaces( comp_surfs ); 05771 05772 CubitString name("COMPOSITE_GEOM"); 05773 std::vector<CubitString> string_list; 05774 string_list.push_back( name ); 05775 CubitSimpleAttrib geom_attrib( &string_list, 0, 0 ); 05776 05777 int i, j; 05778 05779 for( i = comp_surfs.size(); i--; ) 05780 { 05781 CompositeSurface* csurf = 05782 dynamic_cast<CompositeSurface*>(comp_surfs.get_and_step()); 05783 assert(csurf!= NULL ); 05784 05785 for( j = 0; j < csurf->num_surfs(); j++ ) 05786 { 05787 append_attrib( csurf, geom_attrib ); 05788 geom_attrib.int_data_list().clear(); 05789 } 05790 } 05791 05792 return CUBIT_SUCCESS; 05793 } 05794 05795 CubitStatus CompositeEngine::save( CompositeBody* ) 05796 { return CUBIT_SUCCESS; } 05797 05798 05799 CompositePoint* CompositeEngine::stitch_points( TBPoint* pt1, TBPoint* pt2 ) 05800 { 05801 CompositePoint* cp1 = dynamic_cast<CompositePoint*>(pt1); 05802 CompositePoint* cp2 = dynamic_cast<CompositePoint*>(pt2); 05803 if( !cp1 ) cp1 = replace_point( pt1 ); 05804 if( !cp2 ) cp2 = replace_point( pt2 ); 05805 05806 while( CompositeCurve* curve = cp2->next_curve() ) 05807 { 05808 if( curve->start_point() == cp2 ) 05809 curve->start_point( cp1 ); 05810 if( curve->end_point() == cp2 ) 05811 curve->end_point( cp1 ); 05812 } 05813 05814 cp1->stitch( cp2 ); 05815 return cp1; 05816 } 05817 05818 CompositeCurve* CompositeEngine::stitch_curves( Curve* curve1, Curve* curve2 ) 05819 { 05820 CompositeCurve* c1 = dynamic_cast<CompositeCurve*>(curve1); 05821 CompositeCurve* c2 = dynamic_cast<CompositeCurve*>(curve2); 05822 if( !c1 ) c1 = replace_curve( curve1 ); 05823 if( !c2 ) c2 = replace_curve( curve2 ); 05824 05825 bool reversed = false, fail = false; 05826 if( c1->start_point() == c2->end_point() ) 05827 reversed = true; 05828 else if( c1->start_point() != c2->start_point() ) 05829 fail = true; 05830 05831 if (c1->start_point() == c1->end_point()) 05832 { 05833 CubitVector pt, tan1, tan2, junk; 05834 c1->position_from_fraction( 0.5, pt ); 05835 c1->closest_point( pt, junk, &tan1 ); 05836 c2->closest_point( pt, junk, &tan2 ); 05837 reversed = (tan1 % tan2) < 0.0; 05838 } 05839 05840 if( fail || 05841 (reversed && c1->end_point() != c2->start_point()) || 05842 (!reversed && c1->end_point() != c2->end_point()) ) 05843 { 05844 if( c1->num_curves() == 1 ) 05845 remove_composite( c1 ); 05846 if( c2->num_curves() == 1 ) 05847 remove_composite( c2 ); 05848 return 0; 05849 } 05850 05851 //while( CompositeCoEdge* coedge = c2->first_coedge() ) 05852 //{ 05853 //c2->remove( coedge ); 05854 //c1->add( coedge ); 05855 //if( reversed ) 05856 // coedge->reverse(); 05857 //} 05858 CompositeCoEdge* coedge = 0; 05859 if (reversed) while ((coedge = c2->next_coedge( coedge ))) 05860 coedge->reverse(); 05861 05862 05863 c1->stitch( c2 ); 05864 return c1; 05865 } 05866 05867 CompositeSurface* 05868 CompositeEngine::stitch_surfaces( Surface* /*surf1*/, Surface* /*surf2*/ ) 05869 { 05870 return 0; 05871 /* 05872 CompositeSurface* cs1 = dynamic_cast<CompositeSurface*>(surf1); 05873 CompositeSurface* cs2 = dynamic_cast<CompositeSurface*>(surf2); 05874 05875 // Can only stitch pairs of surfaces. Fail if either 05876 // surface is already stitched with another surface. 05877 if( (cs1 && cs1->get_stitch_partner()) || 05878 (cs2 && cs2->get_stitch_partner()) ) 05879 return 0; 05880 05881 if( ! cs1 ) cs1 = replace_surface( surf1 ); 05882 if( ! cs2 ) cs2 = replace_surface( surf2 ); 05883 05884 // special case - topological sphere 05885 if( !cs1->first_loop() && !cs2->first_loop() ) 05886 { 05887 if( cs1->stitch( cs2 ) ) 05888 return cs1; // success 05889 05890 if( !cs1->has_hidden_entities() ) 05891 remove_composite( cs1 ); 05892 if( !cs2->has_hidden_entities() ) 05893 remove_composite( cs2 ); 05894 return 0; // fail 05895 } 05896 05897 // make sure all curves are merged 05898 CompositeLoop* loop = 0; 05899 bool reversed = false; 05900 bool failed = false; 05901 while( !failed && (loop = cs1->next_loop(loop)) ) 05902 { 05903 CompositeCoEdge* coedge = loop->first_coedge(); 05904 do 05905 { 05906 if( ! coedge->get_curve()->find_coedge( cs2 ) ) 05907 { 05908 failed = true; 05909 break; 05910 } 05911 coedge = coedge->next(); 05912 } 05913 while( coedge != loop->first_coedge() ); 05914 } 05915 05916 if( failed ) 05917 { 05918 if( ! cs1->has_hidden_entities() ) 05919 remove_composite( cs1 ); 05920 if( ! cs2->has_hidden_entities() ) 05921 remove_composite( cs2 ); 05922 05923 return 0; 05924 } 05925 05926 while( CompositeCoSurf* cosurf = cs2->next_co_surface() ) 05927 { 05928 cs2->remove( cosurf ); 05929 cs1->add( cosurf ); 05930 if( reversed ) 05931 { 05932 CubitSense sense = cosurf->sense(); 05933 sense = sense == CUBIT_REVERSED ? CUBIT_FORWARD : CUBIT_REVERSED; 05934 cosurf->sense( sense ); 05935 } 05936 } 05937 cs1->stitch( cs2 ); 05938 05939 return cs1; 05940 */ 05941 } 05942 05943 TBPoint* CompositeEngine::insert_point(CompositeCurve* curve, double u) 05944 { 05945 int i, index; 05946 double param; 05947 TBPoint *result = 0; 05948 CubitVector position; 05949 DLIList<TBPoint*> pts; 05950 double tolsqr = GEOMETRY_RESABS*GEOMETRY_RESABS; 05951 TBPoint *start, *end; 05952 DLIList<TopologyBridge*> pt_list; 05953 Curve *rcurve = 0; 05954 05955 // Get the curve in the CompositeCurve on which the 05956 // parameter u lies. 05957 if( ! curve->curve_param( u, param, index ) ) 05958 return 0; 05959 rcurve = curve->get_curve(index); 05960 05961 // Get the position corresponding with u. 05962 if( !rcurve->position_from_u(param,position) ) 05963 return 0; 05964 05965 // Get the CompositeCurve's hidden points. We will 05966 // first see if the position to insert is on top of 05967 // one of the hidden points. 05968 curve->get_hidden_points(pts); 05969 for(i=pts.size(); i--;) 05970 { 05971 TBPoint *cur_pt = pts.get_and_step(); 05972 05973 // Don't use GEOMETRY_RESABS if we can get a 05974 // value from the solid modeling engine. 05975 double tmp_tol = tolsqr; 05976 CompositePoint *cp = dynamic_cast<CompositePoint*>(cur_pt); 05977 GeometryQueryEngine *gqe = NULL; 05978 if(cp) 05979 { 05980 TBPoint *real_pt = cp->get_point(); 05981 gqe = real_pt->get_geometry_query_engine(); 05982 } 05983 else 05984 gqe = cur_pt->get_geometry_query_engine(); 05985 if(gqe) 05986 { 05987 double tmp_tol = gqe->get_sme_resabs_tolerance(); 05988 tmp_tol *= tmp_tol; 05989 if(tmp_tol > tolsqr) 05990 tolsqr = tmp_tol; 05991 } 05992 if( (cur_pt->coordinates() - position).length_squared() < tmp_tol ) 05993 { 05994 result = cur_pt; 05995 i = 0; 05996 } 05997 } 05998 05999 // If the insert position wasn't one of the hidden 06000 // points look at the ends of the underlying curves 06001 // to see if it is one of the end points. 06002 if(!result) 06003 { 06004 rcurve->get_children_virt(pt_list); 06005 assert(pt_list.size()); 06006 pt_list.reset(); 06007 start = dynamic_cast<TBPoint*>(pt_list.get()); 06008 end = dynamic_cast<TBPoint*>(pt_list.next()); 06009 assert( start && end ); 06010 06011 if( (start->coordinates() - position).length_squared() < tolsqr ) 06012 { 06013 result = start; 06014 } 06015 else if( (end->coordinates() - position).length_squared() < tolsqr ) 06016 { 06017 result = end; 06018 } 06019 else 06020 { 06021 // If the insert position wasn't one of the end points go 06022 // ahead and insert a point into the curve. 06023 result = PartitionEngine::instance().insert_point(rcurve,param); 06024 if( !result ) 06025 return 0; 06026 } 06027 } 06028 06029 // Work with a real point here because functions called from 06030 // restore_point_in_curve() may remove the composite all together 06031 // leaving us with a stale CompositePoint pointer at this level. 06032 CompositePoint *comp_pt = dynamic_cast<CompositePoint*>(result); 06033 if(comp_pt) 06034 result = comp_pt->get_point(); 06035 06036 // Finally, undo the composite. 06037 if ( ! restore_point_in_curve( result ) ) 06038 return 0; 06039 06040 TBPoint* comp = dynamic_cast<CompositePoint*>(result->owner()); 06041 return comp ? comp : result; 06042 } 06043 06044 TBPoint* CompositeEngine::insert_point_curve( CompositeSurface* surf, 06045 const CubitVector& pos ) 06046 { 06047 // find closest surface 06048 int i = surf->closest_underlying_surface( pos ); 06049 Surface *dummy_surf, *real_surf = surf->get_surface(i); 06050 06051 TBPoint* pt = PartitionEngine::instance().insert_point_curve( real_surf, pos, dummy_surf ); 06052 if ( !pt ) 06053 return 0; 06054 06055 if (!restore_point(pt)) 06056 return 0; 06057 06058 return dynamic_cast<CompositePoint*>(pt->owner()); 06059 } 06060 06061 int CompositeEngine::is_hidden(TopologyBridge *tb) 06062 { 06063 int ret = 0; 06064 int done = 0; 06065 TopologyBridge *cur_bridge = tb; 06066 while(!done) 06067 { 06068 TBOwner *tbowner = cur_bridge->owner(); 06069 if(dynamic_cast<BridgeManager*>(tbowner)) 06070 { 06071 done = 1; 06072 ret = 0; 06073 } 06074 else if(dynamic_cast<HiddenEntitySet*>(tbowner)) 06075 { 06076 done = 1; 06077 ret = 1; 06078 } 06079 cur_bridge = dynamic_cast<TopologyBridge*>(tbowner); 06080 if(!cur_bridge) 06081 done = 1; 06082 } 06083 return ret; 06084 } 06085 06086 CubitStatus CompositeEngine::insert_curve( DLIList<Surface*>& surfaces, 06087 DLIList<CubitVector*>& polyline, 06088 DLIList<Surface*>& new_surfaces, 06089 DLIList<Curve*>& new_curves ) 06090 { 06091 int i; 06092 06093 DLIList<Surface*> surfs_to_reverse; 06094 DLIList<Surface*> real_surfs; 06095 DLIList<TBPoint*> points; 06096 surfaces.reset(); 06097 06098 for ( i = surfaces.size(); i--; ) 06099 { 06100 Surface* surf = surfaces.get_and_step(); 06101 CompositeSurface* comp = dynamic_cast<CompositeSurface*>(surf); 06102 if ( !comp ) 06103 { 06104 real_surfs.append(surf); 06105 continue; 06106 } 06107 06108 // Partitioning needs all of the surfaces involved in the partition 06109 // to have facets oriented in the same direction w.r.t. the volume (in or out). 06110 // For surface facets that will have to be flipped we also want to reverse 06111 // the sense of the PartitionSurfaces to be consistent. Therefore, we 06112 // create a list here of surfaces/facets that need to be flipped. We 06113 // will use the sense info from the CompositeSurface to determine this. 06114 for ( int j = 0; j < comp->num_surfs(); j++ ) 06115 { 06116 real_surfs.append( comp->get_surface( j ) ); 06117 if(comp->get_sense(j) == CUBIT_REVERSED) 06118 surfs_to_reverse.append(comp->get_surface(j)); 06119 } 06120 06121 // append all real points visible on composite surfaces 06122 // to list. 06123 CompositeLoop* loop = 0; 06124 while( (loop = comp->next_loop(loop) ) != NULL ) 06125 { 06126 CompositeCoEdge* coe = loop->first_coedge(); 06127 do { 06128 points.append(coe->get_curve()->start_point()->get_point()); 06129 points.append(coe->get_curve()->end_point()->get_point()); 06130 coe = coe->next(); 06131 } while( coe != loop->first_coedge() ); 06132 } 06133 } 06134 06135 CubitStatus s = PartitionEngine::instance(). 06136 insert_curve( real_surfs, polyline, new_surfaces, new_curves, NULL, 06137 surfs_to_reverse.size() ? &surfs_to_reverse : NULL); 06138 if ( !s ) 06139 return CUBIT_FAILURE; 06140 06141 new_curves.last(); 06142 for ( i = new_curves.size(); i--; ) 06143 { 06144 Curve* curve = new_curves.step_and_get(); 06145 CompositeCurve* ccurve = dynamic_cast<CompositeCurve*>(curve->owner()); 06146 if ( !ccurve ) continue; 06147 06148 restore_curve( ccurve ); 06149 ccurve = dynamic_cast<CompositeCurve*>(curve->owner()); 06150 if ( ccurve ) 06151 new_curves.change_to(ccurve); 06152 } 06153 06154 // The remainder of this function tries to composite over 06155 // 2-valence vertics in the chain of resulting curves. 06156 // These vertices are the result of intersections with 06157 // hidden curves. If there is only one result curve, then 06158 // skip the rest. 06159 if (new_curves.size() == 1) 06160 { 06161 clean_out_deactivated_geometry(); 06162 return CUBIT_SUCCESS; 06163 } 06164 06165 06166 // Remove any 2-valence vertices in chain of resulting curves. 06167 // These are intersections with hidden curves. 06168 new_curves.reset(); 06169 Curve* prev_curve = new_curves.get(); 06170 DLIList<TopologyBridge*> prev_pts(2), next_pts(2), pt_curves; 06171 DLIList<TBPoint*> dead_points; 06172 prev_curve->get_children( prev_pts, false, COMPOSITE_LAYER ); 06173 for ( i = new_curves.size(); i--; ) 06174 { 06175 Curve* curve = new_curves.step_and_get(); 06176 curve->get_children( next_pts, false, COMPOSITE_LAYER ); 06177 while( prev_pts.size() ) 06178 { 06179 TBPoint* point = dynamic_cast<TBPoint*>(prev_pts.pop()); 06180 if( !next_pts.move_to( point ) ) 06181 continue; 06182 next_pts.extract(); 06183 06184 pt_curves.clean_out(); 06185 point->get_parents( pt_curves ); 06186 if ( pt_curves.size() != 2 || points.is_in_list(point) ) 06187 continue; 06188 06189 if ( CompositePoint* comp = dynamic_cast<CompositePoint*>(point) ) 06190 if ( points.is_in_list(comp->get_point()) ) 06191 continue; 06192 06193 dead_points.append( point ); 06194 prev_pts.clean_out(); 06195 } 06196 06197 prev_pts = next_pts; 06198 next_pts.clean_out(); 06199 } 06200 06201 06202 while( dead_points.size() ) 06203 { 06204 TBPoint* point = dead_points.pop(); 06205 if ( CompositePoint* comp = dynamic_cast<CompositePoint*>(point->owner()) ) 06206 point = comp; 06207 06208 pt_curves.clean_out(); 06209 point->get_parents( pt_curves ); 06210 if ( pt_curves.size() == 1 ) 06211 continue; 06212 assert(pt_curves.size() == 2); 06213 06214 CompositeCurve* keep = remove_point(point); 06215 if (!keep) 06216 continue; 06217 06218 bool add = true; 06219 if ( pt_curves.move_to(keep) ) 06220 { 06221 pt_curves.extract(); 06222 add = false; 06223 } 06224 06225 while( pt_curves.size() ) 06226 { 06227 Curve* stale_ptr = reinterpret_cast<Curve*>(pt_curves.pop()); 06228 if ( new_curves.move_to( stale_ptr ) ) 06229 { 06230 if ( add ) 06231 { 06232 new_curves.change_to( keep ); 06233 add = false; 06234 } 06235 else 06236 { 06237 new_curves.remove(); 06238 } 06239 } 06240 } 06241 if ( add ) 06242 new_curves.append( keep ); 06243 } 06244 06245 clean_out_deactivated_geometry(); 06246 return CUBIT_SUCCESS; 06247 } 06248 06249 //------------------------------------------------------------------------- 06250 // Purpose : Update for destroted underlying topology 06251 // 06252 // Special Notes : 06253 // 06254 // Creator : Jason Kraftcheck 06255 // 06256 // Creation Date : 06/14/04 06257 //------------------------------------------------------------------------- 06258 void CompositeEngine::notify_deactivated (CompositeBody* body) 06259 { 06260 while (CompositeLump* vol_ptr = body->next_lump(NULL)) 06261 { 06262 body->remove( vol_ptr ); 06263 } 06264 deactivatedList.append_unique( body ); 06265 } 06266 06267 //------------------------------------------------------------------------- 06268 // Purpose : Update for destroted underlying topology 06269 // 06270 // Special Notes : 06271 // 06272 // Creator : Jason Kraftcheck 06273 // 06274 // Creation Date : 06/14/04 06275 //------------------------------------------------------------------------- 06276 void CompositeEngine::notify_deactivated( CompositeLump* vol ) 06277 { 06278 while (CompositeShell* shell = vol->next_shell(NULL)) 06279 { 06280 while (CompositeCoSurf* cosurf = shell->first_co_surf()) 06281 { 06282 shell->remove( cosurf ); 06283 CompositeSurface* surf = cosurf->get_surface(); 06284 if (surf) 06285 surf->remove( cosurf ); 06286 delete cosurf; 06287 } 06288 vol->remove( shell ); 06289 deactivatedList.append_unique( shell ); 06290 } 06291 deactivatedList.append_unique( vol ); 06292 } 06293 06294 06295 //------------------------------------------------------------------------- 06296 // Purpose : Update for destroted underlying topology 06297 // 06298 // Special Notes : 06299 // 06300 // Creator : Jason Kraftcheck 06301 // 06302 // Creation Date : 07/31/03 06303 //------------------------------------------------------------------------- 06304 void CompositeEngine::notify_deactivated (CompositeSurface* surface) 06305 { 06306 while (CompositeCoSurf* cosurf_ptr = surface->next_co_surface(NULL)) 06307 { 06308 if (cosurf_ptr->get_shell()) 06309 cosurf_ptr->get_shell()->remove(cosurf_ptr); 06310 surface->remove(cosurf_ptr); 06311 delete cosurf_ptr; 06312 } 06313 06314 while (CompositeLoop* loop_ptr = surface->first_loop()) 06315 { 06316 while (CompositeCoEdge* coedge_ptr = loop_ptr->first_coedge()) 06317 { 06318 CompositeCurve* curve = coedge_ptr->get_curve(); 06319 if (curve) 06320 { 06321 curve->remove(coedge_ptr); 06322 // Clean up point-curves with surface... 06323 if (curve->num_curves() == 0) 06324 notify_deactivated(curve); 06325 } 06326 loop_ptr->remove(coedge_ptr); 06327 deactivatedList.append_unique(coedge_ptr); 06328 } 06329 surface->remove(loop_ptr); 06330 deactivatedList.append_unique(loop_ptr); 06331 } 06332 deactivatedList.append_unique(surface); 06333 } 06334 06335 void CompositeEngine::notify_deactivated (CompositeCurve* curve) 06336 { 06337 while (CompositeCoEdge* coedge_ptr = curve->next_coedge(NULL)) 06338 { 06339 if (coedge_ptr->get_loop()) 06340 coedge_ptr->get_loop()->remove(coedge_ptr); 06341 curve->remove(coedge_ptr); 06342 deactivatedList.append_unique(coedge_ptr); 06343 } 06344 06345 if (curve->start_point()) 06346 curve->start_point(0); 06347 if (curve->end_point()) 06348 curve->end_point(0); 06349 06350 deactivatedList.append_unique(curve); 06351 } 06352 06353 void CompositeEngine::notify_deactivated (CompositePoint* point) 06354 { 06355 while (CompositeCurve* curve_ptr = point->next_curve(NULL)) 06356 { 06357 if (point == curve_ptr->start_point()) 06358 curve_ptr->start_point(0); 06359 if (point == curve_ptr->end_point()) 06360 curve_ptr->end_point(0); 06361 } 06362 06363 deactivatedList.append_unique(point); 06364 } 06365 06366 void CompositeEngine::clean_out_deactivated_geometry() 06367 { 06368 while (deactivatedList.size()) 06369 delete deactivatedList.pop(); 06370 } 06371 06372 06373 CubitStatus CompositeEngine::translate( CompositeBody* body, 06374 const CubitVector& delta ) 06375 { 06376 assert (body && delta.length_squared()); 06377 return CUBIT_FAILURE; 06378 } 06379 06380 CubitStatus CompositeEngine::rotate( CompositeBody* body, 06381 const CubitVector& axis, 06382 double degrees ) 06383 { 06384 assert( body && axis.length_squared() && degrees ); 06385 return CUBIT_FAILURE; 06386 } 06387 06388 CubitStatus CompositeEngine::scale( CompositeBody* body, 06389 const CubitVector& factors ) 06390 { 06391 assert( body && factors.x() && factors.y() && factors.z() ); 06392 return CUBIT_FAILURE; 06393 } 06394 06395 CubitStatus CompositeEngine::reflect( CompositeBody* body, 06396 const CubitVector& axis ) 06397 06398 { 06399 assert( body && axis.length() ); 06400 return CUBIT_FAILURE; 06401 } 06402 06403 CubitStatus CompositeEngine::restore_transform( CompositeBody* body ) 06404 { 06405 assert( 0 != body ); 06406 return CUBIT_FAILURE; 06407 } 06408 06409 06410 CubitStatus CompositeEngine::translate( CompositeSurface* surf, 06411 const CubitVector& delta ) 06412 { 06413 assert (surf && delta.length_squared()); 06414 return CUBIT_FAILURE; 06415 } 06416 06417 CubitStatus CompositeEngine::rotate( CompositeSurface* surf, 06418 const CubitVector& axis, 06419 double degrees ) 06420 { 06421 assert( surf && axis.length_squared() && degrees ); 06422 return CUBIT_FAILURE; 06423 } 06424 06425 CubitStatus CompositeEngine::scale( CompositeSurface* surf, 06426 const CubitVector& factors ) 06427 { 06428 assert( surf && factors.x() && factors.y() && factors.z() ); 06429 return CUBIT_FAILURE; 06430 } 06431 06432 CubitStatus CompositeEngine::reflect( CompositeSurface* surf, 06433 const CubitVector& axis ) 06434 06435 { 06436 assert( surf && axis.length() ); 06437 return CUBIT_FAILURE; 06438 } 06439 06440 06441 CubitStatus CompositeEngine::translate( CompositeCurve* curve, 06442 const CubitVector& delta ) 06443 { 06444 assert (curve && delta.length_squared()); 06445 return CUBIT_FAILURE; 06446 } 06447 06448 CubitStatus CompositeEngine::rotate( CompositeCurve* curve, 06449 const CubitVector& axis, 06450 double degrees ) 06451 { 06452 assert( curve && axis.length_squared() && degrees ); 06453 return CUBIT_FAILURE; 06454 } 06455 06456 CubitStatus CompositeEngine::scale( CompositeCurve* curve, 06457 const CubitVector& factors ) 06458 { 06459 assert( curve && factors.x() && factors.y() && factors.z() ); 06460 return CUBIT_FAILURE; 06461 } 06462 06463 CubitStatus CompositeEngine::reflect( CompositeCurve* curve, 06464 const CubitVector& axis ) 06465 06466 { 06467 assert( curve && axis.length() ); 06468 return CUBIT_FAILURE; 06469 } 06470 06471 CubitStatus CompositeEngine::notify_transform( TopologyBridge* bridge, 06472 const CubitTransformMatrix& xform ) 06473 { 06474 int i; 06475 DLIList<TopologyBridge*> lumps, shells, surfaces, tmp_list; 06476 06477 if (BodySM* body_sm = dynamic_cast<BodySM*>(bridge)) 06478 body_sm->get_children( lumps, true, COMPOSITE_LAYER); 06479 else if (Lump* lump = dynamic_cast<Lump*>(bridge)) 06480 lumps.append(lump); 06481 else if (ShellSM* shell = dynamic_cast<ShellSM*>(bridge)) 06482 shells.append(shell); 06483 else if (Surface* surface = dynamic_cast<Surface*>(bridge)) 06484 surfaces.append(surface); 06485 else 06486 return CUBIT_SUCCESS; 06487 06488 for (i = lumps.size(); i--; ) 06489 { 06490 TopologyBridge* lump = lumps.step_and_get(); 06491 CompositeLump* comp_lump = dynamic_cast<CompositeLump*>(lump); 06492 if (comp_lump) 06493 comp_lump->update(); 06494 } 06495 06496 while (lumps.size()) 06497 { 06498 TopologyBridge* lump = lumps.pop(); 06499 tmp_list.clean_out(); 06500 lump->get_children( tmp_list, true, COMPOSITE_LAYER ); 06501 shells += tmp_list; 06502 } 06503 06504 while (shells.size()) 06505 { 06506 TopologyBridge* shell = shells.pop(); 06507 tmp_list.clean_out(); 06508 shell->get_children( tmp_list, true, COMPOSITE_LAYER ); 06509 surfaces += tmp_list; 06510 } 06511 06512 for (i = surfaces.size(); i--; ) 06513 { 06514 TopologyBridge* surface = surfaces.step_and_get(); 06515 CompositeSurface* composite = dynamic_cast<CompositeSurface*>(surface); 06516 if (composite) 06517 { 06518 composite->notify_transformed(); 06519 composite->update(); 06520 } 06521 DLIList<Curve*> curves; 06522 surface->curves(curves); 06523 int j; 06524 for (j = 0; j < curves.size(); j++) 06525 { 06526 CompositeCurve* comp = 06527 dynamic_cast<CompositeCurve*>(curves.get_and_step()); 06528 if (comp) 06529 comp->update(); 06530 } 06531 } 06532 06533 double det = xform.sub_matrix( 3, 3 ).determinant(); 06534 bool reverse = det < 0.0; 06535 if (!reverse) 06536 return CUBIT_SUCCESS; 06537 06538 // if we get here, the transform was a reflection so we need to make sure all 06539 // loops and coedges get reversed 06540 DLIList<TopologyBridge*> loops; 06541 DLIList<TopologyBridge*> tmp_loops; 06542 DLIList<TopologyBridge*> coedges; 06543 06544 while (surfaces.size()) 06545 { 06546 surfaces.pop()->get_children( tmp_loops, true, COMPOSITE_LAYER ); 06547 loops += tmp_loops; 06548 while (tmp_loops.size()) 06549 { 06550 tmp_loops.pop()->get_children( tmp_list, true, COMPOSITE_LAYER ); 06551 coedges += tmp_list; 06552 tmp_list.clean_out(); 06553 } 06554 } 06555 06556 // reverse loops and coedges separately, since composite coedges in non-composite 06557 // loops also need to be reversed 06558 bool b_reverse_coedges = false; 06559 while (loops.size()) 06560 { 06561 CompositeLoop* loop = dynamic_cast<CompositeLoop*>(loops.pop()); 06562 if (loop) 06563 loop->reverse(b_reverse_coedges); 06564 } 06565 06566 // reverse the coedges 06567 while (coedges.size()) 06568 { 06569 CompositeCoEdge* comp = dynamic_cast<CompositeCoEdge*>(coedges.pop()); 06570 if (comp) 06571 { 06572 comp->reverse(); 06573 } 06574 } 06575 06576 return CUBIT_SUCCESS; 06577 } 06578 06579 06580 //------------------------------------------------------------------------- 06581 // Purpose : Combine bodies 06582 // 06583 // Special Notes : 06584 // 06585 // Creator : Jason Kraftcheck 06586 // 06587 // Creation Date : 06/11/04 06588 //------------------------------------------------------------------------- 06589 CompositeBody* CompositeEngine::combine_bodies( BodySM* body1, BodySM* body2 ) 06590 { 06591 CompositeBody* comp1 = dynamic_cast<CompositeBody*>(body1); 06592 if (!comp1) 06593 comp1 = dynamic_cast<CompositeBody*>(body1->owner()); 06594 if (!comp1) 06595 comp1 = replace_body( body1 ); 06596 06597 CompositeBody* comp2 = dynamic_cast<CompositeBody*>(body2); 06598 if (!comp2) 06599 comp2 = dynamic_cast<CompositeBody*>(body2->owner()); 06600 if (!comp2) 06601 comp2 = replace_body( body2 ); 06602 06603 assert(comp1 && comp2); 06604 if (comp1 == comp2) 06605 return comp1; 06606 06607 comp1->combine( comp2 ); 06608 06609 while (CompositeLump* lump = comp2->next_lump(0)) 06610 { 06611 comp2->remove( lump ); 06612 comp1->add( lump ); 06613 } 06614 06615 delete comp2; 06616 return comp1; 06617 } 06618 06619 void CompositeEngine::get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge, 06620 DLIList<TopologyBridge*> &tbs ) 06621 { 06622 TBOwner* tb_owner = source_bridge->owner(); 06623 CompositeSurface *comp_surf = CAST_TO(tb_owner, CompositeSurface ); 06624 if( comp_surf ) 06625 { 06626 if( comp_surf->bridge_manager() ) 06627 { 06628 tbs.append( comp_surf ); 06629 return; 06630 } 06631 } 06632 06633 CompositeCurve *comp_curve = CAST_TO(tb_owner, CompositeCurve ); 06634 if( comp_curve ) 06635 { 06636 if( comp_curve->bridge_manager() ) 06637 { 06638 tbs.append( comp_curve ); 06639 return; 06640 } 06641 } 06642 06643 CompositePoint *comp_pt = CAST_TO(tb_owner, CompositePoint ); 06644 if( comp_pt ) 06645 { 06646 if( comp_pt->bridge_manager() ) 06647 { 06648 tbs.append( comp_pt ); 06649 return; 06650 } 06651 } 06652 06653 HiddenEntitySet *hidden_ent_set = CAST_TO(tb_owner, HiddenEntitySet ); 06654 if( hidden_ent_set ) 06655 { 06656 TBOwner *owner = hidden_ent_set->owner(); 06657 CompositeCurve *comp_curve = CAST_TO(owner, CompositeCurve ); 06658 if( comp_curve && comp_curve->bridge_manager() ) 06659 { 06660 tbs.append( comp_curve ); 06661 return; 06662 } 06663 06664 CompositeSurface *comp_surf = CAST_TO(owner, CompositeSurface ); 06665 if( comp_surf ) 06666 return; 06667 06668 assert(0); 06669 } 06670 else 06671 { 06672 CompositePoint *comp_pt = CAST_TO(tb_owner, CompositePoint); 06673 06674 if( comp_pt ) 06675 { 06676 TBOwner *other_owner = comp_pt->owner(); 06677 06678 HiddenEntitySet *hidden_ent_set = CAST_TO(other_owner, HiddenEntitySet ); 06679 if( hidden_ent_set ) 06680 { 06681 TBOwner *owner = hidden_ent_set->owner(); 06682 CompositeCurve *comp_curve = CAST_TO(owner, CompositeCurve ); 06683 if( comp_curve && comp_curve->bridge_manager() ) 06684 { 06685 tbs.append( comp_curve ); 06686 return; 06687 } 06688 06689 CompositeSurface *comp_surf = CAST_TO(owner, CompositeSurface ); 06690 if( comp_surf && comp_surf->bridge_manager() ) 06691 { 06692 tbs.append( comp_surf ); 06693 return; 06694 } 06695 } 06696 } 06697 06698 CompositeCurve *comp_curve = CAST_TO(tb_owner, CompositeCurve); 06699 06700 if( comp_curve ) 06701 { 06702 TBOwner *other_owner = comp_curve->owner(); 06703 06704 HiddenEntitySet *hidden_ent_set = CAST_TO(other_owner, HiddenEntitySet ); 06705 if( hidden_ent_set ) 06706 { 06707 TBOwner *owner = hidden_ent_set->owner(); 06708 CompositeSurface *comp_surf = CAST_TO(owner, CompositeSurface ); 06709 if( comp_surf->bridge_manager() ) 06710 { 06711 tbs.append( comp_surf ); 06712 return; 06713 } 06714 } 06715 } 06716 } 06717 06718 return; 06719 } 06720 06721