cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : GeometryModifyTool.cpp 00003 // 00004 // Purpose : The tool used to create and modify geometry 00005 // 00006 // Special Notes : 00007 // 00008 // Creator : Tim Tautges 00009 // 00010 // Creation Date : 2/01 00011 // 00012 //------------------------------------------------------------------------- 00013 00014 #include <string.h> 00015 #include <assert.h> 00016 #include <stdlib.h> 00017 #include <math.h> 00018 #include <sstream> 00019 //#include <iostream> 00020 00021 #include "GeometryModifyTool.hpp" 00022 #include "CubitDefines.h" 00023 #include "GeometryDefines.h" 00024 #include "GeometryEntity.hpp" 00025 #include "GeometryQueryTool.hpp" 00026 #include "MergeTool.hpp" 00027 #include "SurfaceOverlapTool.hpp" 00028 #include "GeometryQueryEngine.hpp" 00029 #include "OldUnmergeCode.hpp" 00030 #include "GeometryModifyEngine.hpp" 00031 #include "AnalyticGeometryTool.hpp" 00032 #include "DAG.hpp" 00033 #include "TopologyBridge.hpp" 00034 #include "ModelQueryEngine.hpp" 00035 #include "CADefines.hpp" 00036 #include "GeomMeasureTool.hpp" 00037 #include "LocalToleranceTool.hpp" 00038 00039 #include "RefEntity.hpp" 00040 #include "RefEntityFactory.hpp" 00041 #include "RefEntityName.hpp" 00042 #include "BasicTopologyEntity.hpp" 00043 #include "RefVertex.hpp" 00044 #include "RefEdge.hpp" 00045 #include "RefFace.hpp" 00046 #include "RefVolume.hpp" 00047 00048 #include "CoVertex.hpp" 00049 #include "CoEdge.hpp" 00050 #include "CoFace.hpp" 00051 #include "CoVolume.hpp" 00052 00053 #include "Chain.hpp" 00054 #include "Loop.hpp" 00055 #include "Shell.hpp" 00056 #include "Body.hpp" 00057 00058 #include "Lump.hpp" 00059 #include "Surface.hpp" 00060 #include "Curve.hpp" 00061 #include "Point.hpp" 00062 #include "BodySM.hpp" 00063 #include "ShellSM.hpp" 00064 #include "LoopSM.hpp" 00065 #include "CoEdgeSM.hpp" 00066 00067 #include "CubitAttrib.hpp" 00068 #include "CubitVector.hpp" 00069 #include "CubitPlane.hpp" 00070 #include "CubitTransformMatrix.hpp" 00071 #include "GfxPreview.hpp" 00072 #include "AppUtil.hpp" 00073 00074 #include "DLIList.hpp" 00075 00076 #include "CubitMessage.hpp" 00077 #include "SettingHandler.hpp" 00078 00079 #include "CastTo.hpp" 00080 #include "CpuTimer.hpp" 00081 00082 #include "BridgeManager.hpp" 00083 #include "SplitSurfaceTool.hpp" 00084 #include "OffsetSplitTool.hpp" 00085 #include "AutoMidsurfaceTool.hpp" 00086 #include "TDSurfaceOverlap.hpp" 00087 #include "GfxDebug.hpp" 00088 00089 #include "CubitUndo.hpp" 00090 00091 /* Work around stupid #define hz equal to HZ on IBM */ 00092 #ifdef hz 00093 # undef hz 00094 #endif 00095 #ifdef PROE 00096 #include "CompositeTool.hpp" 00097 #endif 00098 00099 GeometryModifyTool* GeometryModifyTool::instance_ = 0; 00100 CubitBoolean GeometryModifyTool::allEdgesImprint = CUBIT_TRUE; 00101 CubitBoolean GeometryModifyTool::groupImprint = CUBIT_TRUE; 00102 CubitBoolean GeometryModifyTool::newIds = CUBIT_FALSE; 00103 CubitBoolean GeometryModifyTool::sepAfterWebcut = CUBIT_TRUE; 00104 CubitBoolean GeometryModifyTool::booleanRegularize = CUBIT_TRUE; 00105 CubitBoolean GeometryModifyTool::uniteMixedModels = CUBIT_TRUE; 00106 CubitBoolean GeometryModifyTool::oldNames = CUBIT_FALSE; 00107 CubitBoolean GeometryModifyTool::meshAutodelete = CUBIT_TRUE; 00108 CubitBoolean GeometryModifyTool::meshAutodeleteRemesh = CUBIT_FALSE; 00109 RefEntity* GeometryModifyTool::copyingEntity = NULL; 00110 00111 CubitStatus prepare_surface_sweep( 00112 DLIList<BodySM*> &blank_bodies, 00113 DLIList<Surface*> &surfaces, 00114 const CubitVector& sweep_vector, 00115 bool sweep_perp, 00116 bool through_all, 00117 bool outward, 00118 bool up_to_next, 00119 Surface *stop_surf, 00120 Curve *curve_to_sweep_along, 00121 BodySM* &cutting_tool_ptr , 00122 const CubitVector* point = NULL, 00123 double *angle = NULL); 00124 // prepare for webcut with swept_surfaces. if point and angle is known, 00125 // do surface sweep rotated; or if curve_to_sweep_along is known, do 00126 // sweep along curve; then if sweep_perp is true, do perpendicular sweep 00127 // of the surfaces; lastly do sweep along vector. 00128 00129 CubitStatus webcut_w_cylinder( DLIList<BodySM*> &webcut_body_list, 00130 double radius, 00131 const CubitVector &axis, 00132 const CubitVector ¢er, 00133 DLIList<BodySM*>& neighbor_imprint_list, 00134 DLIList<BodySM*>& results_list, 00135 ImprintType imprint_type = NO_IMPRINT ); 00136 //- webcuts a body using a cylinder given the input parameters. 00137 00138 //------------------------------------------------------------------------- 00139 // Purpose : Controls access and creation of the sole instance of this 00140 // class. 00141 // 00142 // Special Notes : 00143 // 00144 // Creator : Xuechen Liu 00145 // 00146 // Creation Date : 07/11/96 00147 //------------------------------------------------------------------------- 00148 00149 GeometryModifyTool* GeometryModifyTool::instance(GeometryModifyEngine *GMEPtr) 00150 { 00151 // Check to see if we have created an instance of the class 00152 // If not, proceed to create one. 00153 00154 if (instance_ == 0) 00155 { 00156 // When creating the instance, we should always have a valid 00157 // SMEPtr. If not, complain. 00158 00159 instance_ = new GeometryModifyTool (GMEPtr) ; 00160 00161 // check to make sure there's a ref entity factory extant 00162 //RefEntityFactory *factory = 00163 RefEntityFactory::instance(); 00164 } 00165 00166 // If there is an existing instance of the class, check if there 00167 // was a request to set default solid modeling engine. If so, be nice 00168 // to the calling routine :) :) and kindly set the default solid 00169 // modeling engine. 00170 00171 else if ( GMEPtr != NULL && instance_->gmeList.move_to(GMEPtr)) { 00172 delete instance_->gmeList.remove(); 00173 instance_->gmeList.insert(GMEPtr); 00174 } 00175 00176 // Return the a pointer to the instance of the class. 00177 00178 return instance_ ; 00179 } 00180 00181 //------------------------------------------------------------------------- 00182 // Purpose : Destructor. 00183 // 00184 // Special Notes : 00185 // 00186 // Creator : Xuechen Liu 00187 // 00188 // Creation Date : 07/11/96 00189 //------------------------------------------------------------------------- 00190 GeometryModifyTool::~GeometryModifyTool () 00191 { 00192 instance_ = NULL; 00193 //Kill the geometry modify engine(s) 00194 int i; 00195 for (i = gmeList.size(); i > 0; i--) 00196 delete gmeList.get_and_step(); 00197 00198 gmeList.clean_out(); 00199 } 00200 00201 //------------------------------------------------------------------------- 00202 // Purpose : Deletes instance variable 00203 // 00204 // Special Notes : 00205 // 00206 // Creator : Corey Ernst 00207 // 00208 // Creation Date : 12/31/07 00209 //------------------------------------------------------------------------- 00210 void GeometryModifyTool::delete_instance() 00211 { 00212 if( NULL != instance_ ) 00213 { 00214 delete instance_; 00215 instance_ = NULL; 00216 } 00217 } 00218 00219 //------------------------------------------------------------------------- 00220 // Purpose : Creates a Body corresponding to a sphere with the 00221 // given radius 00222 // 00223 // Special Notes : 00224 // 00225 // Creator : Jihong Ma 00226 // 00227 // Creation Date : 09/18/96 00228 //------------------------------------------------------------------------- 00229 Body* GeometryModifyTool::sphere(double radius, 00230 int x_shift, 00231 int y_shift, 00232 int z_shift, 00233 double inner_radius, 00234 bool delete_side ) 00235 { 00236 if (0 == gmeList.size()) 00237 { 00238 PRINT_WARNING("No active geometry engine.\n"); 00239 return NULL; 00240 } 00241 00242 // First make sure the radius is not zero or less 00243 if ( radius <= 0.0 ) 00244 { 00245 PRINT_ERROR("In GeometryModifyTool::sphere\n" 00246 " Cannot make a sphere of radius %f\n", 00247 radius); 00248 return NULL ; 00249 } 00250 00251 if( CubitUndo::get_undo_enabled() ) 00252 CubitUndo::save_state(); 00253 00254 GeometryModifyEngine *gme = gmeList.get(); 00255 00256 BodySM* body_sm = gme->sphere(radius); 00257 00258 if (x_shift != 0 || y_shift != 0 || z_shift != 0) 00259 { 00260 BodySM *brick = gme->brick( 2.0 * radius, 00261 2.0 * radius, 00262 2.0 * radius); 00263 00264 CubitVector delta( x_shift * radius, 00265 y_shift * radius, 00266 z_shift * radius ); 00267 00268 gme->get_gqe()->translate( brick, delta ); 00269 00270 DLIList<BodySM*> new_sms; 00271 DLIList<BodySM*> from_bodies(1); 00272 from_bodies.append( body_sm ); 00273 bool keep_old = true; 00274 CubitStatus bool_status; 00275 if( delete_side == false ) 00276 bool_status = gme->intersect( brick, from_bodies, new_sms, keep_old ); 00277 else 00278 { 00279 DLIList<BodySM*> tool_bodies(1); 00280 tool_bodies.append( brick ); 00281 bool imprint = false; 00282 bool_status = gme->subtract( tool_bodies, from_bodies, new_sms, imprint, keep_old ); 00283 } 00284 00285 //delete the old bodies 00286 gme->get_gqe()->delete_solid_model_entities( body_sm ); 00287 gme->get_gqe()->delete_solid_model_entities( brick ); 00288 00289 if( bool_status == CUBIT_FAILURE || new_sms.size() == 0 ) 00290 { 00291 PRINT_ERROR("Problems creating sphere.\n" ); 00292 return NULL ; 00293 } 00294 00295 body_sm = new_sms.get(); 00296 } 00297 00298 Body *new_body = NULL; 00299 BodySM* inner_body_sm = NULL; 00300 if( inner_radius ) 00301 { 00302 inner_body_sm = gme->sphere(inner_radius); 00303 DLIList<BodySM*> new_sms; 00304 DLIList<BodySM*> from_bodies(1); 00305 DLIList<BodySM*> tool_bodies(1); 00306 from_bodies.append( body_sm ); 00307 tool_bodies.append( inner_body_sm ); 00308 bool imprint = false; 00309 bool keep_old = true; 00310 CubitStatus subtract_status = 00311 gme->subtract( tool_bodies, from_bodies, new_sms, imprint, keep_old ); 00312 00313 //delete the old bodies 00314 gme->get_gqe()->delete_solid_model_entities( body_sm ); 00315 gme->get_gqe()->delete_solid_model_entities( inner_body_sm ); 00316 00317 if( subtract_status == CUBIT_FAILURE || new_sms.size() == 0 ) 00318 { 00319 PRINT_ERROR("Problems creating sphere with inner radius.\n" ); 00320 return NULL ; 00321 } 00322 00323 body_sm = new_sms.get(); 00324 } 00325 00326 if (!body_sm) 00327 { 00328 PRINT_ERROR("In GeometryModifyTool::sphere\n" 00329 " Problems building a volume from the sphere.\n"); 00330 } 00331 else 00332 new_body = GeometryQueryTool::instance()->make_Body(body_sm); 00333 00334 if( CubitUndo::get_undo_enabled() ) 00335 { 00336 if( new_body ) 00337 CubitUndo::note_result_body( new_body ); 00338 else 00339 CubitUndo::remove_last_undo(); 00340 } 00341 00342 return new_body; 00343 } 00344 00345 //------------------------------------------------------------------------- 00346 // Purpose : Creates a Body corresponding to a brick with given width, 00347 // depth, and height. 00348 // 00349 // Special Notes : 00350 // 00351 // Creator : Jihong Ma 00352 // 00353 // Creation Date : 09/18/96 00354 //------------------------------------------------------------------------- 00355 Body* GeometryModifyTool::brick(double width, double depth, double height) 00356 { 00357 if (0 == gmeList.size()) 00358 { 00359 PRINT_WARNING("No active geometry engine.\n"); 00360 return NULL; 00361 } 00362 00363 // First make sure that none of the input values are zero or less 00364 if ( width <= GEOMETRY_RESABS || depth <= GEOMETRY_RESABS || height <= GEOMETRY_RESABS ) 00365 { 00366 PRINT_ERROR("In GeometryModifyTool::brick\n" 00367 " Cannot make a cuboid of size %f x %f x %f\n" 00368 " All dimensions must be > 0.0\n", 00369 width, depth, height); 00370 return NULL; 00371 } 00372 00373 if( CubitUndo::get_undo_enabled() ) 00374 CubitUndo::save_state(); 00375 00376 Body *new_body = NULL; 00377 BodySM* bodyPtr = gmeList.get()->brick(width, depth, height); 00378 00379 if (bodyPtr == NULL) 00380 { 00381 PRINT_ERROR("In GeometryModifyTool::brick\n" 00382 " Problem creating a brick.\n") ; 00383 } 00384 else 00385 new_body = GeometryQueryTool::instance()->make_Body(bodyPtr); 00386 00387 if( CubitUndo::get_undo_enabled() ) 00388 { 00389 if( new_body ) 00390 CubitUndo::note_result_body( new_body ); 00391 else 00392 CubitUndo::remove_last_undo(); 00393 } 00394 00395 return new_body; 00396 } 00397 00398 #ifdef KCM_MESH_TO_GEOM 00399 //------------------------------------------------------------------------- 00400 // Purpose : Create breps from mesh entities. 00401 // 00402 // Special Notes : 00403 // 00404 // Creator : Brett Clark 00405 // 00406 // Creation Date : 12/21/2010 00407 //------------------------------------------------------------------------- 00408 CubitStatus GeometryModifyTool::mesh2brep(std::vector<double> &xvals, 00409 std::vector<double> &yvals, 00410 std::vector<double> &zvals, 00411 std::vector<unsigned int> &tri_connectivity, 00412 DLIList<BodySM*> &new_body_sms) 00413 { 00414 if (0 == gmeList.size()) 00415 { 00416 PRINT_WARNING("No active geometry engine.\n"); 00417 return CUBIT_FAILURE; 00418 } 00419 00420 return gmeList.get()->mesh2brep(xvals, yvals, zvals, tri_connectivity, new_body_sms); 00421 } 00422 #endif 00423 00424 //------------------------------------------------------------------------- 00425 // Purpose : Creates a Body corresponding to a brick at given location, 00426 // orientation, and size. 00427 // 00428 // Special Notes : If one of the dimensions is zero, a planar sheet is created. 00429 // 00430 // Creator : Steve Storm 00431 // 00432 // Creation Date : 10/09/2000 00433 //------------------------------------------------------------------------- 00434 Body* GeometryModifyTool::brick(const CubitVector ¢er, 00435 const CubitVector axes[3], 00436 const CubitVector &extension) 00437 { 00438 if (0 == gmeList.size()) 00439 { 00440 PRINT_WARNING("No active geometry engine.\n"); 00441 return NULL; 00442 } 00443 00444 double width = 2.0*extension.x(); 00445 double height = 2.0*extension.y(); 00446 double depth = 2.0*extension.z(); 00447 // First make sure that entity creation is possible. Allow at most 00448 // only one of the dimensions to be zero - in which case a planar 00449 // sheet is created. 00450 if ( width < 0.0 || height < 0.0 || depth < 0.0 ) 00451 { 00452 PRINT_ERROR( "Cannot make a brick of size %f x %f x %f\n" 00453 " Negative dimensions are not allowed.\n", 00454 width, height, depth ); 00455 return NULL ; 00456 } 00457 00458 int wz = width < GEOMETRY_RESABS; 00459 int hz = height < GEOMETRY_RESABS; 00460 int dz = depth < GEOMETRY_RESABS; 00461 if( wz || hz || dz ) 00462 { 00463 if( (wz + hz + dz) > 1 ) 00464 { 00465 PRINT_ERROR( "Cannot make a sheet of size %f x %f x %f\n" 00466 " At least two dimensions must be nonzero.\n", 00467 width, height, depth ); 00468 return NULL ; 00469 } 00470 00471 // Make a sheet body instead of a cuboid 00472 CubitVector sheet_axes[2]; 00473 if( wz ) 00474 { 00475 sheet_axes[0] = axes[1]; 00476 sheet_axes[1] = axes[2]; 00477 return planar_sheet( center, sheet_axes, height, depth ); 00478 } 00479 else if( hz ) 00480 { 00481 sheet_axes[0] = axes[2]; 00482 sheet_axes[1] = axes[0]; 00483 return planar_sheet( center, sheet_axes, depth, width ); 00484 } 00485 else 00486 { 00487 sheet_axes[0] = axes[0]; 00488 sheet_axes[1] = axes[1]; 00489 return planar_sheet( center, sheet_axes, width, height ); 00490 } 00491 } 00492 else 00493 { 00494 if( CubitUndo::get_undo_enabled() ) 00495 CubitUndo::save_state(); 00496 00497 BodySM* bodyPtr = gmeList.get()->brick(center, axes, extension) ; 00498 Body *new_body = NULL; 00499 if (bodyPtr == NULL) 00500 { 00501 PRINT_ERROR("In GeometryTool::brick\n" 00502 " Problem creating a brick.\n") ; 00503 } 00504 else 00505 new_body = GeometryQueryTool::instance()->make_Body(bodyPtr); 00506 00507 if( CubitUndo::get_undo_enabled() ) 00508 { 00509 if( new_body ) 00510 CubitUndo::note_result_body( new_body ); 00511 else 00512 CubitUndo::remove_last_undo(); 00513 } 00514 00515 return new_body; 00516 } 00517 } 00518 00519 //------------------------------------------------------------------------- 00520 // Purpose : Creates a Body corresponding to a prism with height, 00521 // sides, major, minor radii 00522 // 00523 // 00524 // Special Notes : 00525 // 00526 // Creator : Jihong Ma 00527 // 00528 // Creation Date : 09/18/96 00529 //------------------------------------------------------------------------- 00530 Body* GeometryModifyTool::prism( double height, int sides, double major, double minor) 00531 { 00532 if (0 == gmeList.size()) 00533 { 00534 PRINT_WARNING("No active geometry engine.\n"); 00535 return NULL; 00536 } 00537 00538 // First make sure that the input values make sense 00539 if ( major < minor || 00540 major <= GEOMETRY_RESABS || minor <= GEOMETRY_RESABS || 00541 height <= GEOMETRY_RESABS || sides < 3 ) 00542 { 00543 PRINT_ERROR("In GeometryModifyTool::prism\n" 00544 " Cannot make a prism of major-radius = %f," 00545 " minor-radius = %f, height = %f, and" 00546 " number of sides = %d\n" 00547 " All dimensions must be > 0.0, the major-radius\n" 00548 " should be greater than or equal to the minor-" 00549 "radius,\n and the number of sides should be greater" 00550 " than 2.\n", major, minor, height, sides); 00551 00552 return NULL; 00553 } 00554 00555 if( CubitUndo::get_undo_enabled() ) 00556 CubitUndo::save_state(); 00557 00558 // Create a Body that represents the prism 00559 BodySM* bodyPtr = gmeList.get()->prism(height, sides, major, minor) ; 00560 Body *new_body = NULL; 00561 if (bodyPtr == NULL) 00562 { 00563 PRINT_ERROR("In GeometryModifyTool::prism\n" 00564 " Problems building a volume from the prism.\n") ; 00565 } 00566 else 00567 new_body = GeometryQueryTool::instance()->make_Body(bodyPtr); 00568 00569 if( CubitUndo::get_undo_enabled() ) 00570 { 00571 if( new_body ) 00572 CubitUndo::note_result_body( new_body ); 00573 else 00574 CubitUndo::remove_last_undo(); 00575 } 00576 00577 return new_body; 00578 } 00579 00580 //------------------------------------------------------------------------- 00581 // Purpose : Creates a Body corresponding to a pyramid with given 00582 // height, major, minor,top, sides 00583 // 00584 // Special Notes : 00585 // 00586 // Creator : Jihong Ma 00587 // 00588 // Creation Date : 09/18/96 00589 //------------------------------------------------------------------------- 00590 Body* GeometryModifyTool::pyramid ( double height, int sides, double major, 00591 double minor, double top) 00592 { 00593 if (0 == gmeList.size()) 00594 { 00595 PRINT_WARNING("No active geometry engine.\n"); 00596 return NULL; 00597 } 00598 00599 // First make sure that the input values make sense 00600 if ( major < minor || 00601 major <= GEOMETRY_RESABS || minor <= GEOMETRY_RESABS || 00602 height <= GEOMETRY_RESABS || top < 0.0 || sides < 3 ) 00603 { 00604 PRINT_ERROR("In GeometryModifyTool::pyramid\n" 00605 " Cannot make a pyramid of major-radius = %f," 00606 " minor-radius = %f, height = %f," 00607 " top %f, and number of sides = %d\n" 00608 " All dimensions must be > 0.0, the major-radius" 00609 " should be greater than the minor-radius, the " 00610 "number of sides should be greater than 2.\n", 00611 major, minor, height, top, sides); 00612 return NULL; 00613 } 00614 00615 if( CubitUndo::get_undo_enabled() ) 00616 CubitUndo::save_state(); 00617 00618 // Create a Body that represents the prism 00619 BodySM* bodyPtr = gmeList.get()->pyramid ( height, sides, major, minor, top); 00620 Body *new_body = NULL; 00621 if (bodyPtr == NULL) 00622 { 00623 PRINT_ERROR("In GeometryModifyTool::pyramid\n" 00624 " Problems building a volume from the pyramid.\n"); 00625 } 00626 else 00627 new_body = GeometryQueryTool::instance()->make_Body(bodyPtr); 00628 00629 if( CubitUndo::get_undo_enabled() ) 00630 { 00631 if( new_body ) 00632 CubitUndo::note_result_body( new_body ); 00633 else 00634 CubitUndo::remove_last_undo(); 00635 } 00636 00637 return new_body; 00638 } 00639 00640 //------------------------------------------------------------------------- 00641 // Purpose : Creates a Body corresponding to a frustum of a cone with 00642 // height, 00643 // input radius in x-direction at base 00644 // input radius in y-direction at base 00645 // input radius in x-direction at top 00646 // 00647 // Special Notes : 00648 // 00649 // Creator : Jihong Ma 00650 // 00651 // Creation Date : 09/18/96 00652 //------------------------------------------------------------------------- 00653 Body* GeometryModifyTool::cylinder ( double hi, double r1, double r2, double r3 ) 00654 { 00655 if (0 == gmeList.size()) 00656 { 00657 PRINT_WARNING("No active geometry engine.\n"); 00658 return NULL; 00659 } 00660 00661 // First make sure that the input values make sense 00662 if ( hi <= GEOMETRY_RESABS || r1 <= GEOMETRY_RESABS || 00663 r2 <= GEOMETRY_RESABS || r3 < 0.0 ) 00664 { 00665 PRINT_ERROR("In GeometryModifyTool::cylinder\n" 00666 " Cannot make a frustum of a cone with height = %f," 00667 " lower x-direction radius = %f," 00668 " lower y-direction radius = %f, and " 00669 "top radius = %f\n" 00670 " All dimensions must be > 0.0\n", 00671 hi, r1, r2, r3); 00672 return NULL; 00673 } 00674 00675 if( CubitUndo::get_undo_enabled() ) 00676 CubitUndo::save_state(); 00677 00678 // Create a Body that represents the prism 00679 BodySM* bodyPtr = gmeList.get()->cylinder( hi, r1, r2, r3); 00680 Body *new_body = NULL; 00681 00682 if (bodyPtr == NULL) 00683 { 00684 PRINT_ERROR("In GeometryModifyTool::cylinder\n" 00685 " Problems building a volume from the conical frustum.\n"); 00686 } 00687 else 00688 new_body = GeometryQueryTool::instance()->make_Body(bodyPtr); 00689 00690 if( CubitUndo::get_undo_enabled() ) 00691 { 00692 if( new_body ) 00693 CubitUndo::note_result_body( new_body ); 00694 else 00695 CubitUndo::remove_last_undo(); 00696 } 00697 00698 return new_body; 00699 } 00700 00701 //------------------------------------------------------------------------- 00702 // Purpose : Creates a Body corresponding to a torus with major_radius 00703 // and minor_radius 00704 // 00705 // 00706 // Special Notes : 00707 // 00708 // Creator : Jihong Ma 00709 // 00710 // Creation Date : 09/18/96 00711 //------------------------------------------------------------------------- 00712 Body* GeometryModifyTool::torus( double r1, double r2 ) 00713 { if (0 == gmeList.size()) 00714 { 00715 PRINT_WARNING("No active geometry engine.\n"); 00716 return NULL; 00717 } 00718 00719 00720 // First make sure that the input values make sense 00721 if ( r1 <= r2 || r1 <= GEOMETRY_RESABS || r2 <= 0.0) 00722 { 00723 PRINT_ERROR("In GeometryModifyTool::torus\n" 00724 " Cannot make a torus of major-radius = %f and" 00725 " minor-radius = %f\n", 00726 r1, r2); 00727 return NULL; 00728 } 00729 00730 if( CubitUndo::get_undo_enabled() ) 00731 CubitUndo::save_state(); 00732 00733 // Create a Body that represents the torus 00734 BodySM* bodyPtr = gmeList.get()->torus(r1, r2) ; 00735 Body *new_body = NULL; 00736 00737 if (bodyPtr == NULL) 00738 { 00739 PRINT_ERROR("In GeometryModifyTool::torus\n" 00740 " Problems building a volume from the torus.\n") ; 00741 } 00742 else 00743 new_body = GeometryQueryTool::instance()->make_Body(bodyPtr); 00744 00745 if( CubitUndo::get_undo_enabled() ) 00746 { 00747 if( new_body ) 00748 CubitUndo::note_result_body( new_body ); 00749 else 00750 CubitUndo::remove_last_undo(); 00751 } 00752 00753 return new_body; 00754 } 00755 00756 //------------------------------------------------------------------------- 00757 // Purpose : Creates a planar sheet with the given corner locations. 00758 // 00759 // Special Notes : 00760 // 00761 // Creator : Steve Storm 00762 // 00763 // Creation Date : 05/10/05 00764 //------------------------------------------------------------------------- 00765 Body* GeometryModifyTool::planar_sheet( const CubitVector& p1, 00766 const CubitVector& p2, 00767 const CubitVector& p3, 00768 const CubitVector& p4 ) 00769 { 00770 if (0 == gmeList.size()) 00771 { 00772 PRINT_WARNING("No active geometry engine.\n"); 00773 return NULL; 00774 } 00775 00776 if( CubitUndo::get_undo_enabled() ) 00777 CubitUndo::save_state(); 00778 00779 // Create a Body that represents the sheet 00780 BodySM* body_ptr = gmeList.get()->planar_sheet(p1, p2, p3, p4) ; 00781 Body *new_body = NULL; 00782 if( body_ptr == NULL ) 00783 { 00784 PRINT_ERROR("In GeometryTool::planar_sheet\n" 00785 " Problems building a volume from the sheet.\n") ; 00786 } 00787 else 00788 new_body = GeometryQueryTool::instance()->make_Body(body_ptr); 00789 00790 if( CubitUndo::get_undo_enabled() ) 00791 { 00792 if( new_body ) 00793 CubitUndo::note_result_body( new_body ); 00794 else 00795 CubitUndo::remove_last_undo(); 00796 } 00797 00798 return new_body; 00799 } 00800 00801 //------------------------------------------------------------------------- 00802 // Purpose : Creates a planar sheet with the given input location, 00803 // orientation and size. 00804 // 00805 // Special Notes : 00806 // 00807 // Creator : Steve Storm 00808 // 00809 // Creation Date : 10/09/00 00810 //------------------------------------------------------------------------- 00811 Body* GeometryModifyTool::planar_sheet ( const CubitVector ¢er, 00812 const CubitVector axes[2], 00813 double width, double height ) 00814 { 00815 if (0 == gmeList.size()) 00816 { 00817 PRINT_WARNING("No active geometry engine.\n"); 00818 return NULL; 00819 } 00820 00821 CubitVector p1, p2, p3, p4; 00822 00823 // Get the corners of the sheet 00824 center.next_point( axes[0], width/2.0, p1 ); 00825 p1.next_point( axes[1], -height/2.0, p1 ); 00826 p1.next_point( axes[1], height, p2 ); 00827 p2.next_point( axes[0], -width, p3 ); 00828 p3.next_point( axes[1], -height, p4 ); 00829 00830 if( CubitUndo::get_undo_enabled() ) 00831 CubitUndo::save_state(); 00832 00833 // Create a Body that represents the sheet 00834 BodySM* body_ptr = gmeList.get()->planar_sheet(p1, p2, p3, p4) ; 00835 Body *new_body = NULL; 00836 00837 if( body_ptr == NULL ) 00838 { 00839 PRINT_ERROR("In GeometryTool::planar_sheet\n" 00840 " Problems building a volume from the sheet.\n") ; 00841 } 00842 else 00843 new_body = GeometryQueryTool::instance()->make_Body(body_ptr); 00844 00845 if( CubitUndo::get_undo_enabled() ) 00846 { 00847 if( new_body ) 00848 CubitUndo::note_result_body( new_body ); 00849 else 00850 CubitUndo::remove_last_undo(); 00851 } 00852 00853 return new_body; 00854 } 00855 00856 //------------------------------------------------------------------------- 00857 // Purpose : Creates a planar sheet with the minimal amount of area 00858 // to cut through the given 3D bounding box. The sheet 00859 // can be extended optionally to make it larger than this 00860 // minimal size. 00861 // 00862 // Special Notes : extension_types: 0-none, 1-percentage, 2-absolute 00863 // 00864 // Creator : Steve Storm 00865 // 00866 // Creation Date : 10/19/98 00867 //------------------------------------------------------------------------- 00868 Body* GeometryModifyTool::planar_sheet ( const CubitPlane& plane, 00869 const CubitBox& bounding_box, 00870 int extension_type, 00871 double extension ) 00872 { 00873 if (0 == gmeList.size()) 00874 { 00875 PRINT_WARNING("No active geometry engine.\n"); 00876 return NULL; 00877 } 00878 00879 CubitVector p1, p2, p3, p4; 00880 00881 // Get the corners of the sheet 00882 if( AnalyticGeometryTool::instance()-> 00883 min_pln_box_int_corners( plane, bounding_box, extension_type, 00884 extension, p1, p2, p3, p4 ) == CUBIT_FAILURE ) 00885 return NULL; 00886 00887 if( CubitUndo::get_undo_enabled() ) 00888 CubitUndo::save_state(); 00889 00890 // Create a Body that represents the sheet 00891 BodySM* body_ptr = gmeList.get()->planar_sheet(p1, p2, p3, p4) ; 00892 Body *new_body = NULL; 00893 00894 if( body_ptr == NULL ) 00895 { 00896 PRINT_ERROR("In GeometryModifyTool::planar_sheet\n" 00897 " Problems building a volume from the sheet.\n") ; 00898 } 00899 else 00900 new_body = GeometryQueryTool::instance()->make_Body(body_ptr); 00901 00902 if( CubitUndo::get_undo_enabled() ) 00903 { 00904 if( new_body ) 00905 CubitUndo::note_result_body( new_body ); 00906 else 00907 CubitUndo::remove_last_undo(); 00908 } 00909 00910 return new_body; 00911 } 00912 00913 Body* GeometryModifyTool::create_body( VolumeFacets& volume, std::map<FacetShapes*, RefEntity*>& entity_map, 00914 const FacetPointSet& points, int interp_order) 00915 { 00916 GeometryModifyEngine* engine = gmeList.get(); 00917 if (!engine->supports_facets()) 00918 return NULL; 00919 00920 Body* new_body = NULL; 00921 00922 if( CubitUndo::get_undo_enabled() ) 00923 CubitUndo::save_state(); 00924 00925 std::map<FacetShapes*, GeometryEntity*> geom_entity_map; 00926 BodySM* body_sm = engine->create_body(volume, geom_entity_map, points, interp_order); 00927 if(body_sm) 00928 { 00929 new_body = GeometryQueryTool::instance()->make_Body(body_sm); 00930 // map information back to caller 00931 std::map<FacetShapes*, GeometryEntity*>::iterator geom_iter; 00932 for (geom_iter = geom_entity_map.begin(); geom_iter != geom_entity_map.end(); geom_iter++) 00933 entity_map[geom_iter->first] = dynamic_cast<RefEntity*>(geom_iter->second->topology_entity()); 00934 } 00935 00936 if( CubitUndo::get_undo_enabled() ) 00937 { 00938 if( new_body ) 00939 CubitUndo::note_result_body( new_body ); 00940 else 00941 CubitUndo::remove_last_undo(); 00942 } 00943 00944 return new_body; 00945 } 00946 00947 RefVertex* GeometryModifyTool::make_RefVertex( RefVertex *vertex ) const 00948 { 00949 if ( vertex == NULL ) 00950 { 00951 PRINT_ERROR("Vertex is NULL\n"); 00952 return NULL; 00953 } 00954 00955 TopologyBridge* bridge = 0; 00956 GeometryModifyEngine* engine = get_engine(vertex, &bridge); 00957 if (engine == NULL) 00958 { 00959 PRINT_ERROR( "%s (vertex %d) does not have a modify engine.\n", 00960 vertex->entity_name().c_str(), 00961 vertex->id() ); 00962 return 0; 00963 } 00964 00965 CubitVector point = vertex->coordinates(); 00966 00967 // Call the default GeometryModifyEngine to create a new TBPoint 00968 TBPoint* point_ptr = engine->make_Point(point); 00969 00970 if( CubitUndo::get_undo_enabled() ) 00971 CubitUndo::save_state(); 00972 00973 // Use the TBPoint to create a RefVertex 00974 RefVertex* ref_vertex_ptr = RefEntityFactory::instance()->construct_RefVertex(point_ptr) ; 00975 00976 if( CubitUndo::get_undo_enabled() ) 00977 { 00978 if( ref_vertex_ptr ) 00979 CubitUndo::note_result_entity( ref_vertex_ptr ); 00980 else 00981 CubitUndo::remove_last_undo(); 00982 } 00983 00984 //transfer the names 00985 DLIList<CubitString> names; 00986 vertex->entity_names( names ); 00987 00988 int i; 00989 for( i=names.size(); i--; ) 00990 { 00991 CubitString tmp_name = names.get_and_step(); 00992 ref_vertex_ptr->entity_name( tmp_name ); 00993 } 00994 00995 // Send a message to the model indicating the vertex was created 00996 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, ref_vertex_ptr)); 00997 00998 // Return the newly created RefVertex 00999 return ref_vertex_ptr ; 01000 } 01001 01002 01003 //------------------------------------------------------------------------- 01004 // Purpose : This function takes a type information and a location 01005 // to create a RefVertex. The underlying representation 01006 // of the RefVertex is determined by the default 01007 // GeometryModifyEngine. 01008 // 01009 // Special Notes : 01010 // 01011 // Creator : Raikanta Sahu 01012 // 01013 // Creation Date : 03/27/97 01014 //------------------------------------------------------------------------- 01015 01016 RefVertex* GeometryModifyTool::make_RefVertex( 01017 CubitVector const& point, int color) const 01018 { 01019 if (0 == gmeList.size()) 01020 { 01021 PRINT_WARNING("No active geometry engine.\n"); 01022 return NULL; 01023 } 01024 01025 // Call the default GeometryModifyEngine to create a new TBPoint 01026 TBPoint* point_ptr = gmeList.get()->make_Point(point); 01027 01028 // If we get a NULL pointer, give a warning message and return 01029 // a NULL pointer. 01030 if ( point_ptr == NULL ) 01031 { 01032 PRINT_WARNING("In GeometryModifyTool::make_RefVertex\n" 01033 " Got a NULL pointer to a TBPoint.\n" 01034 " Cannot make a RefVertex.\n") ; 01035 return (RefVertex *)NULL ; 01036 } 01037 01038 if( CubitUndo::get_undo_enabled() ) 01039 CubitUndo::save_state(); 01040 01041 // Use the TBPoint to create a RefVertex 01042 RefVertex* ref_vertex_ptr = RefEntityFactory::instance()->construct_RefVertex(point_ptr) ; 01043 01044 if( CubitUndo::get_undo_enabled() ) 01045 { 01046 if( ref_vertex_ptr ) 01047 CubitUndo::note_result_entity( ref_vertex_ptr ); 01048 else 01049 CubitUndo::remove_last_undo(); 01050 } 01051 01052 ref_vertex_ptr->color(color); 01053 01054 // Send a message to the model indicating the vertex was created 01055 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::FREE_REF_ENTITY_GENERATED, ref_vertex_ptr)); 01056 01057 // Return the newly created RefVertex 01058 return ref_vertex_ptr ; 01059 } 01060 01061 Body *GeometryModifyTool::make_Body(Surface *surface) const 01062 { 01063 // make a Body from a Surface 01064 BodySM *body_sm = surface->bodysm(); 01065 01066 GeometryModifyEngine* gme = get_engine(surface); 01067 01068 if (gme && !body_sm) 01069 body_sm = gme->make_BodySM(surface); 01070 01071 assert(body_sm != 0); 01072 01073 return GeometryQueryTool::instance()->make_Body(body_sm); 01074 } 01075 01076 //------------------------------------------------------------------------- 01077 // Purpose : This function takes RefEdge type information, too 01078 // 01079 // Creator : David White 01080 // 01081 // Creation Date : 10/9/97 01082 //------------------------------------------------------------------------- 01083 RefEdge* GeometryModifyTool::make_RefEdge(RefEdge *ref_edge_ptr, 01084 bool copy_attribs, 01085 std::map< RefEntity*, RefEntity* > *old_to_new_map ) const 01086 { 01087 if ( ref_edge_ptr == NULL ) 01088 { 01089 PRINT_ERROR("curve is NULL\n"); 01090 return (RefEdge*)NULL; 01091 } 01092 01093 TopologyBridge* bridge = 0; 01094 GeometryModifyEngine* engine = get_engine(ref_edge_ptr, &bridge); 01095 Curve *old_curve = dynamic_cast<Curve*>(bridge); 01096 if (engine == NULL) 01097 { 01098 PRINT_ERROR( "%s (curve %d) does not have a modify engine.\n", 01099 ref_edge_ptr->entity_name().c_str(), 01100 ref_edge_ptr->id() ); 01101 return 0; 01102 } 01103 01104 Curve *tmp_curve; 01105 if( copy_attribs ) 01106 { 01107 DLIList<RefEntity*> tmp_list; 01108 tmp_list.append( ref_edge_ptr ); 01109 TopologyBridge *curve_bridge; 01110 prepare_for_copy( ref_edge_ptr, curve_bridge ); 01111 tmp_curve = CAST_TO( curve_bridge, Curve); 01112 } 01113 else 01114 tmp_curve = old_curve; 01115 01116 std::map<TopologyBridge*, TopologyBridge*> old_tb_to_new_tb; 01117 Curve *new_curve = NULL; 01118 if( old_to_new_map ) 01119 new_curve = engine->make_Curve( tmp_curve, &old_tb_to_new_tb ); 01120 else 01121 new_curve = engine->make_Curve( tmp_curve ); 01122 01123 if (!new_curve) 01124 { 01125 if( copy_attribs ) 01126 clean_up_from_copy_failure( old_curve ); 01127 return (RefEdge *)NULL; 01128 } 01129 01130 TopologyBridge *new_curve_bridge; 01131 if( copy_attribs ) 01132 { 01133 new_curve_bridge = new_curve; 01134 finish_copy( new_curve_bridge, old_curve ); 01135 new_curve = CAST_TO( new_curve_bridge, Curve); 01136 } 01137 01138 if( CubitUndo::get_undo_enabled() ) 01139 CubitUndo::save_state(); 01140 01141 // Complete the task of linking this new Curve into the rest of the 01142 // geometry datastructures and return the new RefEdge. 01143 RefEdge *new_ref_edge = GeometryQueryTool::instance()->make_free_RefEdge(new_curve); 01144 01145 if( old_to_new_map ) 01146 create_old_to_new_ref_ent_map( old_curve, new_curve, *old_to_new_map, old_tb_to_new_tb ); 01147 01148 if( CubitUndo::get_undo_enabled() ) 01149 CubitUndo::note_result_entity( new_ref_edge ); 01150 01151 return new_ref_edge; 01152 } 01153 01154 CubitStatus GeometryModifyTool::prepare_for_copy( RefEntity *ref_ent, 01155 TopologyBridge *&top_bridge ) 01156 { 01157 //save attribute settings 01158 CGMApp::instance()->save_current_attribute_states(); 01159 01160 CGMApp::instance()->attrib_manager()->auto_flag(1); 01161 // Groups are saved directly in the Cubit file, not with attributes 01162 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_GROUP, CUBIT_FALSE); 01163 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_GROUP, CUBIT_FALSE); 01164 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_GROUP, CUBIT_FALSE); 01165 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_GROUP, CUBIT_FALSE); 01166 01167 // The mesh container is only used for the Exodus save/resore method 01168 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_MESH_CONTAINER, CUBIT_FALSE); 01169 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_MESH_CONTAINER, CUBIT_FALSE); 01170 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_MESH_CONTAINER, CUBIT_FALSE); 01171 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_MESH_CONTAINER, CUBIT_FALSE); 01172 01173 // Genesis Entities are saved directly in the Cubit file, not with attributes 01174 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_GENESIS_ENTITY, CUBIT_FALSE); 01175 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_GENESIS_ENTITY, CUBIT_FALSE); 01176 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_GENESIS_ENTITY, CUBIT_FALSE); 01177 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_GENESIS_ENTITY, CUBIT_FALSE); 01178 01179 //Don't save out entity ids 01180 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_ENTITY_ID, CUBIT_FALSE); 01181 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_ENTITY_ID, CUBIT_FALSE); 01182 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_ENTITY_ID, CUBIT_FALSE); 01183 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_ENTITY_ID, CUBIT_FALSE); 01184 01185 //Don't save out graphics 01186 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_GRAPHICS_OPTS, CUBIT_FALSE); 01187 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_GRAPHICS_OPTS, CUBIT_FALSE); 01188 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_GRAPHICS_OPTS, CUBIT_FALSE); 01189 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_GRAPHICS_OPTS, CUBIT_FALSE); 01190 01191 //Flag to say "we're copying" attributes 01192 copyingEntity = ref_ent; 01193 01194 //Get all children 01195 DLIList<RefEntity*> child_list; 01196 ref_ent->get_all_child_ref_entities( child_list ); 01197 01198 //Puts attributes on all the entities 01199 child_list.append( ref_ent ); 01200 CubitAttribUser::auto_update_cubit_attrib( child_list ); 01201 01202 //Prepare virtual 01203 TopologyEntity *topo_ptr = dynamic_cast<TopologyEntity*>( ref_ent ); 01204 top_bridge = topo_ptr->bridge_manager()->topology_bridge(); 01205 DLIList<TopologyBridge*> bridge_list; 01206 bridge_list.append( top_bridge ); 01207 GeometryQueryTool::instance()->ige_export_geom( bridge_list ); 01208 01209 //Should only have 1 bridge in the list 01210 assert( bridge_list.size() == 1 ); 01211 TopologyBridge *tmp_bridge_after = bridge_list.get(); 01212 if( top_bridge != tmp_bridge_after) 01213 top_bridge = tmp_bridge_after; 01214 01215 //Done copying attributes 01216 copyingEntity = NULL; 01217 01218 return CUBIT_SUCCESS; 01219 01220 } 01221 01222 CubitStatus GeometryModifyTool::clean_up_from_copy_failure( TopologyBridge *old_bridge ) 01223 { 01224 //Remove attributes on underlying entities of virtual geometry 01225 //entities which do not have corresponding RefEntities. 01226 DLIList<TopologyBridge*> bridge_list; 01227 bridge_list.append( old_bridge ); 01228 GeometryQueryTool::instance()->ige_remove_attributes( bridge_list ); 01229 01230 //Remove attributes on original entity and children 01231 DLIList<RefEntity*> child_list; 01232 RefEntity *ref_ent = CAST_TO( old_bridge->topology_entity(), RefEntity ); 01233 ref_ent->get_all_child_ref_entities( child_list ); 01234 //child_list.append( ref_ent ); 01235 CubitAttribUser::clear_all_simple_attrib( child_list ); 01236 child_list.clean_out(); 01237 child_list.append( ref_ent ); 01238 CubitAttribUser::clear_all_simple_attrib( child_list ); 01239 01240 CGMApp::instance()->restore_previous_attribute_states(); 01241 01242 return CUBIT_SUCCESS; 01243 } 01244 01245 CubitStatus GeometryModifyTool::finish_copy( TopologyBridge *&new_bridge, 01246 TopologyBridge *old_bridge ) 01247 { 01248 //Remove attributes on underlying entities of virtual geometry 01249 //entities which do not have corresponding RefEntities. 01250 DLIList<TopologyBridge*> bridge_list; 01251 bridge_list.append( old_bridge ); 01252 GeometryQueryTool::instance()->ige_remove_attributes( bridge_list ); 01253 01254 //Remove attributes on original entity and children 01255 DLIList<RefEntity*> child_list; 01256 RefEntity *ref_ent = CAST_TO( old_bridge->topology_entity(), RefEntity ); 01257 ref_ent->get_all_child_ref_entities( child_list ); 01258 //child_list.append( ref_ent ); 01259 CubitAttribUser::clear_all_simple_attrib( child_list ); 01260 child_list.clean_out(); 01261 child_list.append( ref_ent ); 01262 CubitAttribUser::clear_all_simple_attrib( child_list ); 01263 01264 01265 //Restore virtual 01266 //Could create virtual geometry here so the Topology Bridge can change 01267 bridge_list.clean_out(); 01268 bridge_list.append( new_bridge ); 01269 TopologyBridge *tmp_bridge_before = new_bridge; 01270 GeometryQueryTool::instance()->ige_import_geom( bridge_list ); 01271 assert( bridge_list.size() == 1 ); 01272 if( tmp_bridge_before != bridge_list.get() ) 01273 new_bridge = bridge_list.get(); 01274 01275 //make the RefEntities 01276 Curve *curve = NULL; 01277 Surface *surface = NULL; 01278 Lump *lump = NULL; 01279 BodySM *body = NULL; 01280 01281 RefEntity *new_ref_ent = NULL; 01282 if( (curve = CAST_TO( new_bridge, Curve ) ) != NULL ) 01283 new_ref_ent = GeometryQueryTool::instance()->make_RefEdge( curve ); 01284 else if( (surface = CAST_TO( new_bridge, Surface) ) != NULL ) 01285 new_ref_ent = GeometryQueryTool::instance()->make_RefFace( surface ); 01286 else if( (lump = CAST_TO( new_bridge, Lump) ) != NULL ) 01287 new_ref_ent = GeometryQueryTool::instance()->make_Body( lump->bodysm() ); 01288 else if( (body = CAST_TO( new_bridge, BodySM) ) != NULL ) 01289 new_ref_ent = GeometryQueryTool::instance()->make_Body( body ); 01290 01291 //actuate the attributes on everything 01292 child_list.clean_out(); 01293 new_ref_ent->get_all_child_ref_entities( child_list ); 01294 child_list.append( new_ref_ent ); 01295 GeometryQueryTool::import_actuate( child_list ); 01296 01297 //Remove attributes on new entity and children 01298 child_list.clean_out(); 01299 new_ref_ent->get_all_child_ref_entities( child_list ); 01300 CubitAttribUser::clear_all_simple_attrib( child_list ); 01301 child_list.clean_out(); 01302 child_list.append( new_ref_ent ); 01303 CubitAttribUser::clear_all_simple_attrib( child_list ); 01304 01305 CGMApp::instance()->restore_previous_attribute_states(); 01306 return CUBIT_SUCCESS; 01307 } 01308 #ifdef PROE 01309 CubitStatus GeometryModifyTool::prepare_for_topology_update( BodySM* old_bodysm ) 01310 { 01311 DLIList<BodySM*> old_bodysms; 01312 old_bodysms.append(old_bodysm); 01313 01314 do_attribute_setup(); 01315 push_attributes_before_modify( old_bodysms ); 01316 01317 return CUBIT_SUCCESS; 01318 } 01319 CubitStatus GeometryModifyTool::finish_topology_update( BodySM* new_bodysm, 01320 Body* old_body ) 01321 { 01322 DLIList<Body*> input_bodies,result_bodies; 01323 DLIList<BodySM*> new_bodysms, old_bodysms; 01324 input_bodies.append(old_body); 01325 new_bodysms.append(new_bodysm); 01326 old_bodysms.clean_out(); 01327 01328 DLIList<int> merged_surface_ids; 01329 DLIList<int> merged_curve_ids; 01330 01331 01332 get_merged_curve_and_surface_ids( input_bodies, merged_surface_ids, merged_curve_ids ); 01334 //Store information about what surfaces were originally merged 01335 // 01336 //This fixes a problem caused by the lack of support 01337 //for automatically remerging surfaces that contain any 01338 //virtual geometry. 01339 //This should be removed if this issue is ever fixed - AHH 01340 std::map< int , DLIList<Surface*> > merged_map; 01341 for(int i=0; i< merged_surface_ids.size(); i++ ) 01342 { 01343 int refface_id = merged_surface_ids.get_and_step(); 01344 RefFace* old_merged_refface = RefEntityFactory::instance()->get_ref_face( refface_id ); 01345 if( old_merged_refface && old_merged_refface->bridge_manager()->number_of_bridges() > 1 ) 01346 { 01347 DLIList<Surface*> merged_surfsms; 01348 DLIList<TopologyBridge*> bridge_list; 01349 old_merged_refface->bridge_manager()->get_bridge_list( bridge_list ); 01350 for(int j=0; j< bridge_list.size(); j++ ) 01351 { 01352 Surface* merging_surf = CAST_TO(bridge_list.get_and_step(),Surface); 01353 if( merging_surf ) 01354 merged_surfsms.append_unique( merging_surf ); 01355 } 01356 merged_map[ refface_id ] = merged_surfsms; 01357 } 01358 } 01359 //*/ 01360 /* 01361 //check to see if any curves have been orphaned inside virtual geometry 01362 DLIList<TBPoint*> point_list; 01363 new_bodysm->points( point_list ); 01364 CubitBoolean loop = CUBIT_TRUE; 01365 while( loop ) 01366 { 01367 for(i=0; i< point_list.size(); i++) 01368 { 01369 //loop all the points and see if any will be on only one live curve 01370 TBPoint* curr_point = point_list.get_and_step(); 01371 DLIList<Curve*> curves_on_point; 01372 DLIList<Curve*> curves_to_keep; 01373 curr_point->curves( curves_on_point ); 01374 for(int j=0; j< curves_on_point.size(); j++) 01375 { 01376 Curve* curr_curve = curves_on_point.get_and_step(); 01377 DLIList<CubitSimpleAttrib*> attrib_list; 01378 CubitSimpleAttrib* attrib = CompositeEngine::find_attribute_by_name( curr_curve, "COMPOSITE_GEOM" ); 01379 if( attrib ) 01380 { 01381 attrib_list.append(attrib); 01382 } 01383 else 01384 curves_to_keep.append_unique( curr_curve ); 01385 //curr_curve->get_simple_attribute( "COMPOSITE_GEOM", attrib_list ); 01386 //if ( !attrib_list.size() ) 01387 //curves_to_keep.append_unique( curr_curve ); 01388 } 01389 //if all but one curve on this point will be removed we need to remove the other one too 01390 if( curves_to_keep.size() == 1 ) 01391 { 01392 CubitString name("COMPOSITE_GEOM"); 01393 DLIList<CubitString*> string_list; 01394 string_list.append( &name ); 01395 CubitSimpleAttrib geom_attrib( &string_list, 0, 0 ); 01396 curves_to_keep.get()->append_simple_attribute_virt( &geom_attrib ); 01397 curr_point->append_simple_attribute_virt( &geom_attrib ); 01398 loop = CUBIT_FALSE; 01399 } 01400 else if( curves_to_keep.size() == 0 ) 01401 { 01402 DLIList<CubitSimpleAttrib*> attrib_list; 01403 curr_point->get_simple_attribute( "COMPOSIT_GEOM", attrib_list ); 01404 if( !attrib_list.size() ) 01405 { 01406 CubitString name("COMPOSITE_GEOM"); 01407 DLIList<CubitString*> string_list; 01408 string_list.append( &name ); 01409 CubitSimpleAttrib geom_attrib( &string_list, 0, 0 ); 01410 curr_point->append_simple_attribute_virt( &geom_attrib ); 01411 loop = CUBIT_TRUE; 01412 } 01413 } 01414 } 01415 if( loop ) 01416 loop = CUBIT_FALSE; 01417 else 01418 loop = CUBIT_TRUE; 01419 } 01420 */ 01421 GeometryModifyEngine* gme = GeometryModifyTool::instance()->get_engine(old_body); 01422 01423 restore_vg_after_modify(new_bodysms, input_bodies, gme); 01424 01425 01426 DLIList<RefVolume*> volume_list; 01427 01428 int i; 01429 for(i=new_bodysms.size(); i--;) 01430 { 01431 BodySM *bsm = new_bodysms.get_and_step(); 01432 Body *body = dynamic_cast<Body*>(bsm->topology_entity()); 01433 if(body) 01434 { 01435 // Append to the total list of volumes. 01436 body->ref_volumes(volume_list); 01437 } 01438 } 01439 // get all child entities (only get entities below volumes) 01440 DLIList<RefEntity*> child_list, ref_ent_list; 01441 CAST_LIST_TO_PARENT(volume_list, ref_ent_list); 01442 RefEntity::get_all_child_ref_entities( ref_ent_list, child_list ); 01443 01444 // Only push the id attributes if we are doing persistent ids. 01445 for(i=child_list.size(); i--;) 01446 { 01447 child_list.get_and_step()->auto_actuate_cubit_attrib(CUBIT_FALSE,CUBIT_TRUE); 01448 } 01449 01450 remove_pushed_attributes(new_bodysms, input_bodies); 01451 01452 finish_sm_op( input_bodies, new_bodysms , result_bodies); 01453 01454 fixup_merged_entities( merged_surface_ids, merged_curve_ids); 01455 01456 //Look for RefEdges that are orphaned inside of virtual surfaces 01457 CubitBoolean loop = CUBIT_TRUE; 01458 DLIList<RefVertex*> vertex_list; 01459 while(loop) 01460 { 01461 loop = CUBIT_FALSE; 01462 vertex_list.clean_out(); 01463 for(i=0; i< volume_list.size(); i++) 01464 { 01465 RefVolume* curr_volume = volume_list.get_and_step(); 01466 curr_volume->ref_vertices( vertex_list ); 01467 } 01468 for(i=0; i< vertex_list.size(); i++) 01469 { 01470 RefVertex* curr_vertex = vertex_list.get_and_step(); 01471 DLIList<RefEdge*> edges_on_vertex; 01472 curr_vertex->ref_edges( edges_on_vertex ); 01473 edges_on_vertex.uniquify_unordered(); 01474 if( edges_on_vertex.size() == 1 ) 01475 { 01476 RefEdge* edge_to_remove = edges_on_vertex.get(); 01477 CompositeTool::instance()->remove_edge(edge_to_remove); 01478 loop = CUBIT_TRUE; 01479 break; 01480 } 01481 } 01482 } 01484 //Force merge faces that were missed by finish_sm_op 01485 // 01486 //This fixes a problem caused by the lack of support 01487 //for automatically remerging surfaces that contain any 01488 //virtual geometry. 01489 //This should be removed if this issue is ever fixed - AHH 01490 for(i=0; i< merged_surface_ids.size(); i++) 01491 { 01492 int refface_id = merged_surface_ids.get_and_step(); 01493 DLIList<RefFace*> ref_faces_to_remerge; 01494 if(merged_map.find( refface_id ) != merged_map.end()) 01495 { 01496 DLIList<Surface*> merged_surfsms = merged_map[ refface_id ]; 01497 for(int k=0; k< merged_surfsms.size(); k++) 01498 { 01499 Surface* merging_surf = merged_surfsms.get_and_step(); 01500 RefFace* merging_refface = CAST_TO(merging_surf->topology_entity(),RefFace); 01501 if(merging_refface) 01502 ref_faces_to_remerge.append_unique(merging_refface); 01503 } 01504 } 01505 if( ref_faces_to_remerge.size() == 2 ) 01506 { 01507 RefFace* first_remerge_face = ref_faces_to_remerge.get_and_step(); 01508 RefFace* second_remerge_face = ref_faces_to_remerge.get_and_step(); 01509 int first_id = first_remerge_face->id(); 01510 int second_id = second_remerge_face->id(); 01511 MergeTool::instance()->force_merge( first_remerge_face , second_remerge_face ); 01512 PRINT_WARNING("Remerging Surfaces %i and %i\n",first_id,second_id); 01513 } 01514 } 01515 //*/ 01516 //do_attribute_cleanup(); 01517 01518 return CUBIT_SUCCESS; 01519 } 01520 01521 #endif 01522 GeometryModifyEngine* 01523 GeometryModifyTool::make_RefEdge_common( RefVertex* start_vertex, 01524 RefVertex* end_vertex, 01525 TBPoint*& start_point, 01526 TBPoint*& end_point, 01527 RefFace* ref_face, 01528 Surface** surface ) const 01529 { 01530 DLIList<TopologyEntity*> entity_list(3); 01531 DLIList<TopologyBridge*> bridge_list(3); 01532 TopologyBridge* bridge = 0; 01533 GeometryModifyEngine* gme = 0; 01534 start_point = end_point = 0; 01535 01536 bool new_start_point = start_vertex->get_parents() > 0; 01537 bool new_end_point = end_vertex->get_parents() > 0; 01538 01539 if (ref_face) 01540 entity_list.append( ref_face ); 01541 if (!new_start_point) 01542 entity_list.append( start_vertex ); 01543 if (!new_end_point) 01544 entity_list.append( end_vertex ); 01545 01546 if (entity_list.size()) 01547 gme = common_modify_engine( entity_list, bridge_list ); 01548 01549 if (gme) 01550 { 01551 bridge_list.reset(); 01552 if (ref_face) 01553 *surface = dynamic_cast<Surface*>(bridge_list.get_and_step()); 01554 if (!new_start_point) 01555 start_point = dynamic_cast<TBPoint*>(bridge_list.get_and_step()); 01556 if (!new_end_point) 01557 end_point = dynamic_cast<TBPoint*>(bridge_list.get_and_step()); 01558 } 01559 else if (ref_face) 01560 { 01561 gme = get_engine( ref_face, &bridge ); 01562 if (!gme) 01563 { 01564 PRINT_ERROR("No modify engine for surface %d\n", ref_face->id()) ; 01565 return 0; 01566 } 01567 *surface = dynamic_cast<Surface*>(bridge); 01568 GeometryQueryEngine* gqe = bridge->get_geometry_query_engine(); 01569 if (!new_start_point) 01570 start_point = dynamic_cast<TBPoint*>( start_vertex-> 01571 bridge_manager()->topology_bridge( gqe ) ); 01572 if (!new_end_point) 01573 end_point = dynamic_cast<TBPoint*>( end_vertex-> 01574 bridge_manager()->topology_bridge( gqe ) ); 01575 } 01576 else if (!new_start_point && (gme = get_engine( start_vertex, &bridge ))) 01577 { 01578 start_point = dynamic_cast<TBPoint*>(bridge); 01579 if (!new_end_point) 01580 end_point = dynamic_cast<TBPoint*>( end_vertex->bridge_manager()-> 01581 topology_bridge( bridge->get_geometry_query_engine() ) ); 01582 } 01583 else if (!new_end_point && (gme = get_engine( end_vertex, &bridge ))) 01584 { 01585 end_point = dynamic_cast<TBPoint*>(bridge); 01586 } 01587 else 01588 { 01589 gme = get_gme(); 01590 } 01591 01592 01593 if (!start_point) 01594 start_point = gme->make_Point( start_vertex->coordinates() ); 01595 if (!end_point) 01596 end_point = gme->make_Point( end_vertex->coordinates()); 01597 01598 return gme; 01599 } 01600 01601 //------------------------------------------------------------------------- 01602 // Purpose : This function uses the vertices and surface to create 01603 // a curve along this surface. The solid modeler will actually 01604 // do most of the work. 01605 // Note : The optional third vertex will not be part of the curve, 01606 // it is used for interpolation purposes. 01607 // 01608 // Creator : David White 01609 // 01610 // Creation Date : 10/9/97 01611 // 01612 // Rewriting for new GeometryQueryTool interface - J.Kraftcheck 9/03 01613 //------------------------------------------------------------------------- 01614 RefEdge* GeometryModifyTool::make_RefEdge(RefVertex *ref_vertex_1, 01615 RefVertex *ref_vertex_2, 01616 RefFace* ref_face_ptr, 01617 RefVertex const* ref_vertex_3 ) const 01618 { 01619 //make sure that the vertices are on the ref-face. 01620 CubitVector vert_1 = ref_vertex_1->coordinates(); 01621 CubitVector vert_2 = ref_vertex_2->coordinates(); 01622 01623 ref_face_ptr->move_to_surface(vert_1); 01624 ref_face_ptr->move_to_surface(vert_2); 01625 01626 GeometryQueryEngine *gqe = ref_face_ptr->get_geometry_query_engine(); 01627 01628 if (!ref_vertex_1->coordinates().within_tolerance(vert_1, gqe->get_sme_resabs_tolerance())) 01629 { 01630 PRINT_ERROR("vertices must lie within tolerance to the given" 01631 " surface.\n" 01632 "%s (Vertex %d) does not lie on %s (Surface %d).\n", 01633 ref_vertex_1->entity_name().c_str(), 01634 ref_vertex_1->id(), 01635 ref_face_ptr->entity_name().c_str(), 01636 ref_face_ptr->id() ); 01637 return (RefEdge*)NULL; 01638 } 01639 else if (!ref_vertex_2->coordinates().within_tolerance(vert_2, gqe->get_sme_resabs_tolerance() )) 01640 { 01641 PRINT_ERROR("vertices must lie within tolerance to the given" 01642 " surface.\n" 01643 "%s (Vertex %d) does not lie on %s (Surface %d).\n", 01644 ref_vertex_2->entity_name().c_str(), 01645 ref_vertex_2->id(), 01646 ref_face_ptr->entity_name().c_str(), 01647 ref_face_ptr->id() ); 01648 return (RefEdge*)NULL; 01649 } 01650 //Now let us find the points on the surface. We want to 01651 //create them as we go for accuracy. 01652 01653 // Get the GME of the first RefVertex. 01654 GeometryModifyEngine* GMEPtr = 0; 01655 01656 // Extract the end Points to be used to make the RefEdge 01657 TBPoint* point_ptr1 = NULL; 01658 TBPoint* point_ptr2 = NULL; 01659 Surface* surface_ptr = NULL; 01660 01661 // Look for a common GeometryModifyEngine 01662 GMEPtr = make_RefEdge_common( ref_vertex_1, ref_vertex_2, 01663 point_ptr1, point_ptr2, 01664 ref_face_ptr, &surface_ptr ); 01665 01666 //If we did not find a common GeometryModifyEngine, fail 01667 if( ! GMEPtr ) 01668 { 01669 PRINT_ERROR("Surface %d, vertex %d and vertex %d do not " 01670 "belong to the same geometric modeling engine.\n", ref_face_ptr->id(), 01671 ref_vertex_1->id(), ref_vertex_2->id() ); 01672 01673 return 0; 01674 } 01675 01676 CubitVector *third_vector_ptr = NULL; 01677 CubitVector third_vector; 01678 if ( ref_vertex_3 != NULL ) 01679 { 01680 third_vector = ref_vertex_3->coordinates(); 01681 third_vector_ptr = &third_vector; 01682 ref_face_ptr->move_to_surface( third_vector ); 01683 } 01684 01685 // Make sure that we get back valid Points 01686 assert ( point_ptr1 != NULL && point_ptr2 != NULL ); 01687 01688 if( CubitUndo::get_undo_enabled() ) 01689 { 01690 //if endpoints are free vertices, need to save them out 01691 DLIList<RefVertex*> verts_to_save; 01692 verts_to_save.append( ref_vertex_1 ); 01693 verts_to_save.append( ref_vertex_2 ); 01694 bool save_only_if_free = true; 01695 CubitUndo::save_state_with_cubit_file( verts_to_save, save_only_if_free ); 01696 } 01697 01698 // Request the GME to create a Curve using the Points 01699 Curve *curve_ptr; 01700 curve_ptr = GMEPtr->make_Curve( point_ptr1, 01701 point_ptr2, 01702 surface_ptr, 01703 third_vector_ptr); 01704 01705 01706 // If we get a NULL pointer, give a warning message and return 01707 // a NULL pointer. 01708 if ( curve_ptr == NULL ) 01709 { 01710 PRINT_WARNING("In GeometryModifyTool::make_RefEdge\n" 01711 "\tProblems making a spline curve from Vertex %d and %d\n" 01712 "\tand the input list of positions.\n", 01713 ref_vertex_1->id(), ref_vertex_2->id()); 01714 return (RefEdge *)NULL ; 01715 } 01716 01717 01718 // Complete the task of linking this new Curve into the rest of the 01719 // geometry datastructures and return the new RefEdge. 01720 RefEdge *new_edge = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr); 01721 if( CubitUndo::get_undo_enabled() ) 01722 { 01723 if( new_edge ) 01724 CubitUndo::note_result_entity( new_edge ); 01725 } 01726 return new_edge; 01727 } 01728 01729 RefEdge* GeometryModifyTool::make_elliptical_RefEdge( RefVertex *vert1, 01730 RefVertex *vert2, 01731 CubitVector center_point, 01732 double start_angle, 01733 double end_angle, 01734 CubitSense sense) const 01735 { 01736 GeometryModifyEngine* GMEPtr = 0; 01737 01738 // Extract the Points to be used to make the RefEdge 01739 TBPoint* point_ptr1 = NULL; 01740 TBPoint* point_ptr2 = NULL; 01741 01742 // Look for a common geometric modeling engine to use 01743 GMEPtr = make_RefEdge_common( vert1, vert2, 01744 point_ptr1, point_ptr2 ); 01745 if (!GMEPtr) 01746 return 0; 01747 01748 // Make sure that we get back valid Points 01749 assert ( point_ptr1 != NULL && point_ptr2 != NULL ) ; 01750 01751 if( CubitUndo::get_undo_enabled() ) 01752 { 01753 //if endpoints are free vertices, need to save them out 01754 DLIList<RefVertex*> verts_to_save; 01755 verts_to_save.append( vert1 ); 01756 verts_to_save.append( vert2 ); 01757 bool save_only_if_free = true; 01758 CubitUndo::save_state_with_cubit_file( verts_to_save, save_only_if_free ); 01759 } 01760 01761 // Request the GME to create a Curve using the Points 01762 Curve* curve_ptr = GMEPtr->make_elliptical_Curve(point_ptr1, 01763 point_ptr2, 01764 center_point, 01765 start_angle, 01766 end_angle, 01767 sense); 01768 01769 // If we get a NULL pointer, give a warning message and return 01770 // a NULL pointer. 01771 if ( curve_ptr == NULL ) 01772 { 01773 PRINT_WARNING("In GeometryModifyTool::make_elliptical_RefEdge\n" 01774 " Got a NULL pointer to a Curve.\n" 01775 " Problems making RefEdge from RefVertex %d and %d\n", 01776 vert1->id(), vert2->id()); 01777 return (RefEdge *)NULL ; 01778 } 01779 01780 // Complete the task of linking this new Curve into the rest of the 01781 // geometry datastructures and return the new RefEdge. 01782 RefEdge *new_edge = GeometryQueryTool::instance()->make_free_RefEdge( curve_ptr ); 01783 if( CubitUndo::get_undo_enabled() ) 01784 { 01785 if( new_edge ) 01786 CubitUndo::note_result_entity( new_edge ); 01787 } 01788 01789 return new_edge; 01790 } 01791 01792 01793 01794 01795 01796 01797 //------------------------------------------------------------------------- 01798 // Purpose : This function takes RefEdge type information, two 01799 // RefVertices, and a list of positions in space (represented 01800 // by CubitVectors) to create a RefEdge. The RefVertices must 01801 // be associated with the same GeometryModifyEngine. 01802 // The return value can be a NULL pointer, if the RefEdge 01803 // cannot be succesfully made for some reason. 01804 // 01805 // Special Notes : The interpolated curve is a spline curve. 01806 // If the input refface_ptr is not NULL, the points are first 01807 // moved to the surface before interpolation. 01808 // 01809 // Creator : Malcolm Panthaki 01810 // 01811 // Creation Date : 05/15/97 01812 // 01813 // Rewriting for new GeometryQueryTool interface - J.Kraftcheck 9/03 01814 //------------------------------------------------------------------------- 01815 RefEdge* GeometryModifyTool::make_RefEdge(GeometryType ref_edge_type, 01816 RefVertex *ref_vertex_1, 01817 RefVertex *ref_vertex_2, 01818 DLIList<CubitVector*>& vector_list, 01819 RefFace* refface_ptr) const 01820 { 01821 GeometryModifyEngine* GMEPtr = 0; 01822 01823 // Extract the end Points to be used to make the RefEdge 01824 TBPoint* point_ptr1 = NULL; 01825 TBPoint* point_ptr2 = NULL; 01826 Surface* surface_ptr = NULL; 01827 01828 // Look for a common GeometryModifyEngine 01829 GMEPtr = make_RefEdge_common( ref_vertex_1, ref_vertex_2, 01830 point_ptr1, point_ptr2, 01831 refface_ptr, &surface_ptr ); 01832 if (!GMEPtr) 01833 return 0; 01834 01835 // Make sure that we get back valid Points 01836 assert ( point_ptr1 != NULL && point_ptr2 != NULL ); 01837 01838 if( CubitUndo::get_undo_enabled() ) 01839 { 01840 //if endpoints are free vertices, need to save them out 01841 DLIList<RefVertex*> verts_to_save; 01842 verts_to_save.append( ref_vertex_1 ); 01843 verts_to_save.append( ref_vertex_2 ); 01844 bool save_only_if_free = true; 01845 CubitUndo::save_state_with_cubit_file( verts_to_save, save_only_if_free ); 01846 } 01847 01848 // Request the GME to create a Curve using the Points 01849 Curve* curve_ptr = GMEPtr->make_Curve(ref_edge_type, 01850 point_ptr1, 01851 point_ptr2, 01852 vector_list, 01853 refface_ptr ? refface_ptr->get_surface_ptr() : 0); 01854 01855 // If we get a NULL pointer, give a warning message and return 01856 // a NULL pointer. 01857 if ( curve_ptr == NULL ) 01858 { 01859 PRINT_WARNING("In GeometryModifyTool::make_RefEdge\n" 01860 " Got a NULL pointer to a Curve.\n" 01861 " Problems making a spline RefEdge from RefVertex %d and %d\n" 01862 " and the input list of positions.\n", 01863 ref_vertex_1->id(), ref_vertex_2->id()); 01864 return (RefEdge *)NULL ; 01865 } 01866 01867 // Complete the task of linking this new Curve into the rest of the 01868 // geometry datastructures and return the new RefEdge. 01869 RefEdge *new_edge = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr); 01870 if( CubitUndo::get_undo_enabled() ) 01871 { 01872 if( new_edge ) 01873 CubitUndo::note_result_entity( new_edge ); 01874 } 01875 return new_edge; 01876 } 01877 01878 //------------------------------------------------------------------------- 01879 // Purpose : This function takes a type information, two 01880 // RefVertices, an intermediate position, and a sense 01881 // information to create a RefEdge. The RefVertices must 01882 // be associated with the same GeometryModifyEngine. 01883 // The return value can be a NULL pointer, if the RefEdge 01884 // cannot be succesfully made for some reason. 01885 // 01886 // Special Notes : 01887 // 01888 // Creator : Raikanta Sahu 01889 // 01890 // Creation Date : 03/27/97 01891 //------------------------------------------------------------------------- 01892 RefEdge* GeometryModifyTool::make_RefEdge(GeometryType ref_edge_type, 01893 RefVertex *ref_vertex_1, 01894 RefVertex *ref_vertex_2, 01895 CubitVector const* intermediate_point ) const 01896 { 01897 GeometryModifyEngine* GMEPtr = 0; 01898 01899 // Extract the Points to be used to make the RefEdge 01900 TBPoint* point_ptr1 = NULL; 01901 TBPoint* point_ptr2 = NULL; 01902 01903 // Look for a common geometric modeling engine to use 01904 GMEPtr = make_RefEdge_common( ref_vertex_1, ref_vertex_2, 01905 point_ptr1, point_ptr2 ); 01906 if (!GMEPtr) 01907 return 0; 01908 01909 // Make sure that we get back valid Points 01910 assert ( point_ptr1 != NULL && point_ptr2 != NULL ) ; 01911 01912 if( CubitUndo::get_undo_enabled() ) 01913 { 01914 //if endpoints are free vertices, need to save them out 01915 DLIList<RefVertex*> verts_to_save; 01916 verts_to_save.append( ref_vertex_1 ); 01917 verts_to_save.append( ref_vertex_2 ); 01918 bool save_only_if_free = true; 01919 CubitUndo::save_state_with_cubit_file( verts_to_save, save_only_if_free ); 01920 } 01921 01922 // Request the GME to create a Curve using the Points 01923 Curve* curve_ptr = GMEPtr->make_Curve(ref_edge_type, 01924 point_ptr1, 01925 point_ptr2, 01926 intermediate_point ); 01927 01928 // If we get a NULL pointer, give a warning message and return 01929 // a NULL pointer. 01930 if ( curve_ptr == NULL ) 01931 { 01932 PRINT_WARNING("In GeometryModifyTool::make_RefEdge\n" 01933 " Got a NULL pointer to a Curve.\n" 01934 " Problems making RefEdge from RefVertex %d and %d\n", 01935 ref_vertex_1->id(), ref_vertex_2->id()); 01936 return (RefEdge *)NULL ; 01937 } 01938 01939 // Complete the task of linking this new Curve into the rest of the 01940 // geometry datastructures and return the new RefEdge. 01941 RefEdge *new_edge = GeometryQueryTool::instance()->make_free_RefEdge( curve_ptr ); 01942 if( CubitUndo::get_undo_enabled() ) 01943 { 01944 if( new_edge ) 01945 CubitUndo::note_result_entity( new_edge ); 01946 } 01947 return new_edge; 01948 } 01949 01950 //------------------------------------------------------------------------- 01951 // Purpose : This function creates a RefFace from an existing RefFace. 01952 // The new face is a sheet body, double sided face with no 01953 // volume to the body. 01954 // 01955 // Special Notes : 01956 // 01957 // Creator : Raikanta Sahu 01958 // 01959 // Creation Date : 03/27/97 01960 //------------------------------------------------------------------------- 01961 01962 RefFace* GeometryModifyTool::make_RefFace(RefFace *from_ref_face, 01963 std::map< RefEntity*, RefEntity* > *old_to_new_map ) const 01964 { 01965 GeometryModifyEngine* GME_ptr = get_engine(from_ref_face); 01966 01967 if (!GME_ptr) 01968 { 01969 PRINT_ERROR("Cannot create surface from another virtual surface.\n"); 01970 return NULL; 01971 } 01972 //From the surface create a new surface. 01973 TopologyBridge* bridge = 0; 01974 GeometryModifyEngine* engine = get_engine(from_ref_face, &bridge); 01975 Surface* old_surface_ptr = dynamic_cast<Surface*>(bridge); 01976 if ( engine == NULL ) 01977 { 01978 PRINT_ERROR("%s (surface %d) does not have a modify engine.\n", 01979 from_ref_face->entity_name().c_str(), 01980 from_ref_face->id() ); 01981 return (RefFace*)NULL; 01982 } 01983 01984 if( CubitUndo::get_undo_enabled() ) 01985 CubitUndo::save_state(); 01986 01987 //this list will get all the TB's what we'll be copying 01988 TopologyBridge *top_bridge = old_surface_ptr; 01989 01990 01991 //if( !extended_from ) 01992 { 01993 prepare_for_copy( from_ref_face, top_bridge ); 01994 } 01995 01996 Surface *tmp_surface = CAST_TO( top_bridge, Surface ); 01997 std::map< TopologyBridge*, TopologyBridge* > old_tb_to_new_tb; 01998 Surface* new_surface_ptr = engine->make_Surface( tmp_surface, &old_tb_to_new_tb ); 01999 02000 if (!new_surface_ptr) 02001 { 02002 PRINT_ERROR("Surface copy failed.\n"); 02003 //if( !extended_from ) 02004 clean_up_from_copy_failure( old_surface_ptr ); 02005 02006 if( CubitUndo::get_undo_enabled() ) 02007 CubitUndo::remove_last_undo(); 02008 02009 return 0; 02010 } 02011 02012 //if( !extended_from ) 02013 { 02014 TopologyBridge *top_bridge_new = new_surface_ptr; 02015 finish_copy( top_bridge_new, old_surface_ptr ); 02016 new_surface_ptr = CAST_TO( top_bridge_new, Surface ); 02017 } 02018 02019 Body *new_Body = make_Body(new_surface_ptr); 02020 DLIList<RefFace*> ref_faces; 02021 new_Body->ref_faces(ref_faces); 02022 assert(ref_faces.size() > 0); 02023 02024 if( old_to_new_map ) 02025 create_old_to_new_ref_ent_map( tmp_surface, new_surface_ptr, *old_to_new_map, old_tb_to_new_tb ); 02026 02027 if( CubitUndo::get_undo_enabled() ) 02028 { 02029 if( new_Body ) 02030 CubitUndo::note_result_body( new_Body ); 02031 else 02032 CubitUndo::remove_last_undo(); 02033 } 02034 02035 return ref_faces.get(); 02036 } 02037 02038 //------------------------------------------------------------------------- 02039 // Purpose : This function creates a sheet body by extending out a 02040 // set of surfaces. The sheet body is a double sided face 02041 // with no volume. 02042 // 02043 // Special Notes : 02044 // 02045 // Creator : Steve Storm 02046 // 02047 // Creation Date : 02/28/08 02048 //------------------------------------------------------------------------- 02049 Body* 02050 GeometryModifyTool::make_extended_sheet( DLIList<RefFace*> &ref_face_list, 02051 CubitBox *clip_box_ptr, 02052 bool preview ) const 02053 { 02054 if( !ref_face_list.size() ) 02055 return 0; 02056 02057 GfxPreview::clear(); 02058 02059 // Check for virtual geometry 02060 DLIList<RefEntity*> ref_ent_list; 02061 CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list); 02062 if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) ) 02063 { 02064 PRINT_ERROR("EXTENDING surfaces containing virtual geometry is not\n" 02065 " allowed. Delete virtual geometry on these surfaces\n" 02066 " before operation.\n" ); 02067 return 0; 02068 } 02069 02070 // Look for a common GeometryModifyEngine for all of the RefFaces 02071 int count = ref_face_list.size(); 02072 DLIList<TopologyBridge*> bridge_list(count); 02073 DLIList<TopologyEntity*> entity_list(count); 02074 CAST_LIST_TO_PARENT( ref_face_list, entity_list ); 02075 02076 GeometryModifyEngine* GME_ptr = 02077 common_modify_engine( entity_list, bridge_list ); 02078 if(! GME_ptr ) 02079 { 02080 PRINT_ERROR("Cannot construct an extended sheet using surfaces that\n" 02081 " do not share a common geometry engine.\n"); 02082 return 0; 02083 } 02084 02085 DLIList<Surface*> surface_list(count); 02086 CAST_LIST( bridge_list, surface_list, Surface ); 02087 02088 if( CubitUndo::get_undo_enabled() ) 02089 CubitUndo::save_state(); 02090 02091 BodySM *bodySM_ptr = GME_ptr->make_extended_sheet( surface_list, 02092 clip_box_ptr, preview ); 02093 02094 if( !bodySM_ptr ) 02095 CubitUndo::remove_last_undo(); 02096 02097 if( bodySM_ptr ) 02098 { 02099 Body *tmp_body = GeometryQueryTool::instance()->make_Body(bodySM_ptr); 02100 02101 if( CubitUndo::get_undo_enabled() ) 02102 { 02103 if( tmp_body ) 02104 CubitUndo::note_result_entity( tmp_body ); 02105 else 02106 CubitUndo::remove_last_undo(); 02107 } 02108 02109 return tmp_body; 02110 } 02111 else 02112 return 0; 02113 } 02114 02115 //------------------------------------------------------------------------- 02116 // Purpose : This function takes a type information and a list of 02117 // RefEdges to create a Body with just one RefFace. The 02118 // underlying representation of the RefFace is determined 02119 // by the GeometryModifyEngine of the RefEdges. All the 02120 // RefEdges in the list must be associated with the same 02121 // GeometryModifyEngine. The return value can be a 02122 // NULL pointer, if the RefFace cannot be succesfully 02123 // made for some reason. 02124 // 02125 // Special Notes : 02126 // 02127 // Creator : David White 02128 // 02129 // Creation Date : 10/23/97 02130 //------------------------------------------------------------------------- 02131 02132 RefFace* GeometryModifyTool::make_RefFace(GeometryType ref_face_type, 02133 DLIList<RefEdge*>& ref_edge_list, 02134 bool is_free_face, 02135 RefFace *ref_face_ptr, 02136 bool check_edges ) const 02137 { 02138 //Look for a common GeometryModifyEngine for all of 02139 //the RefEdges. 02140 02141 const int count = ref_edge_list.size() + (ref_face_ptr ? 1 : 0); 02142 DLIList<TopologyBridge*> bridge_list(count); 02143 DLIList<TopologyEntity*> entity_list(count); 02144 CAST_LIST_TO_PARENT( ref_edge_list, entity_list ); 02145 if( ref_face_ptr ) entity_list.append( ref_face_ptr ); 02146 02147 GeometryModifyEngine* GME_ptr = 02148 common_modify_engine( entity_list, bridge_list ); 02149 if(! GME_ptr ) 02150 { 02151 PRINT_ERROR("Cannot construct a Surface using entities that do " 02152 "not share a common geometry engine.\n"); 02153 return 0; 02154 } 02155 02156 Surface* old_surface_ptr = 0; 02157 if (ref_face_ptr) 02158 old_surface_ptr = dynamic_cast<Surface*>(bridge_list.pop()); 02159 02160 //Collect all the names on vertices to propagate after you create 02161 //the surface 02162 DLIList<CubitVector> vertex_coordinates; 02163 DLIList<CubitString> vertex_names; 02164 DLIList<RefEdge*> free_ref_edges; 02165 int kk; 02166 for( kk=ref_edge_list.size(); kk--; ) 02167 { 02168 DLIList<CubitString> tmp_names; 02169 RefEdge *tmp_edge = ref_edge_list.get_and_step(); 02170 02171 if( tmp_edge->num_parent_ref_entities() == 0 ) 02172 free_ref_edges.append( tmp_edge ); 02173 02174 RefVertex *s_vertex = tmp_edge->start_vertex(); 02175 RefVertex *e_vertex = tmp_edge->end_vertex(); 02176 int jj; 02177 02178 s_vertex->entity_names( tmp_names ); 02179 for( jj=tmp_names.size(); jj--; ) 02180 { 02181 CubitVector tmp_vec = tmp_edge->start_vertex()->coordinates(); 02182 CubitString name = tmp_names.get_and_step(); 02183 vertex_coordinates.append( tmp_vec ); 02184 vertex_names.append( name ); 02185 } 02186 02187 tmp_names.clean_out(); 02188 e_vertex->entity_names( tmp_names ); 02189 for( jj=tmp_names.size(); jj--; ) 02190 { 02191 CubitVector tmp_vec = tmp_edge->end_vertex()->coordinates(); 02192 CubitString name = tmp_names.get_and_step(); 02193 vertex_coordinates.append( tmp_vec ); 02194 vertex_names.append( name ); 02195 } 02196 } 02197 02198 DLIList<Curve*> curve_list(ref_edge_list.size()); 02199 CAST_LIST( bridge_list, curve_list, Curve ); 02200 02201 // Use the Curves to create a Surface 02202 Surface* surface_ptr = GME_ptr->make_Surface(ref_face_type, curve_list, 02203 old_surface_ptr, check_edges) ; 02204 02205 if (surface_ptr == NULL) { 02206 PRINT_ERROR("Couldn't make new RefFace.\n"); 02207 return NULL; 02208 } 02209 02210 GeometryQueryTool* const gqt = GeometryQueryTool::instance(); 02211 02212 RefFace* result_face = gqt->make_free_RefFace(surface_ptr, is_free_face); 02213 gqt->cleanout_deactivated_geometry(); 02214 02215 //send out events for free curves saying that their 'free' status has 02216 //be changed 02217 02218 for( kk=0; kk<free_ref_edges.size(); kk++ ) 02219 { 02220 RefEdge *free_edge = free_ref_edges.get_and_step(); 02221 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOP_LEVEL_ENTITY_DESTRUCTED, free_edge)); 02222 CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_DELETED, free_edge ); 02223 GeometryQueryTool::instance()->history().add_event(evt); 02224 } 02225 02226 02227 //look for a vertex at the same location of the original 02228 //vertex(s). Add the name to this new vertex. 02229 DLIList<RefVertex*> tmp_verts; 02230 result_face->ref_vertices( tmp_verts); 02231 for( kk=vertex_coordinates.size(); kk--; ) 02232 { 02233 CubitVector tmp_coord = vertex_coordinates.get_and_step(); 02234 CubitString tmp_name = vertex_names.get_and_step(); 02235 02236 int jj; 02237 for( jj=tmp_verts.size(); jj--; ) 02238 { 02239 RefVertex *tmp_vert = tmp_verts.get_and_step(); 02240 if( tmp_coord.distance_between( tmp_vert->coordinates() ) < GEOMETRY_RESABS ) 02241 { 02242 //add the name if it doesn't already exist 02243 RefEntityName::instance()->add_refentity_name( tmp_vert, tmp_name ); 02244 } 02245 } 02246 } 02247 02248 return result_face; 02249 } 02250 02251 //------------------------------------------------------------------------- 02252 // Purpose : This function takes a list of RefVolumes to create a 02253 // Body. The underlying representation of the Body is 02254 // determined by the GeometryModifyEngine of the 02255 // RefVolumes. All the RefVolumes in the list must be 02256 // associated with the same GeometryModifyEngine. The 02257 // return value can be a NULL pointer, if the RefFace 02258 // cannot be succesfully made for some reason. 02259 // 02260 // Special Notes : 02261 // 02262 // Creator : Raikanta Sahu 02263 // 02264 // Creation Date : 03/29/97 02265 //------------------------------------------------------------------------- 02266 02267 Body* GeometryModifyTool::make_Body(DLIList<RefVolume*>& ref_volume_list) const 02268 { 02269 DLIList<TopologyEntity*> topo_list; 02270 DLIList<Lump*> lump_list; 02271 DLIList<TopologyBridge*> bridge_list; 02272 CAST_LIST_TO_PARENT( ref_volume_list, topo_list ); 02273 GeometryModifyEngine* GME_ptr = 02274 common_modify_engine( topo_list, bridge_list, CUBIT_FALSE ); 02275 if( ! GME_ptr ) 02276 { 02277 PRINT_ERROR("The specified volumes do not belong to the same " 02278 "geometry engine, and therefore cannot be used to form a " 02279 "single body."); 02280 return 0; 02281 } 02282 CAST_LIST( bridge_list, lump_list, Lump ); 02283 assert( ref_volume_list.size() == lump_list.size() ); 02284 02285 02286 // Use the Lumps to create a BodySM 02287 BodySM* bodySM_ptr = GME_ptr->make_BodySM(lump_list) ; 02288 02289 // If we get a NULL pointer, give a warning message and return 02290 // a NULL pointer. 02291 if ( bodySM_ptr == NULL ) 02292 { 02293 PRINT_WARNING("In GeometryModifyTool::make_Body\n" 02294 " Got a NULL pointer to a BodySM.\n" 02295 " Cannot make a Body.\n") ; 02296 return (Body *)NULL; 02297 } 02298 02299 return GeometryQueryTool::instance()->make_Body(bodySM_ptr); 02300 } 02301 02302 //------------------------------------------------------------------------- 02303 // Purpose : This function creates a sheet body from an existing 02304 // RefFace. 02305 // 02306 // Special Notes : 02307 // 02308 // Creator : Raikanta Sahu 02309 // 02310 // Creation Date : 03/29/97 02311 //------------------------------------------------------------------------- 02312 02313 Body* GeometryModifyTool::make_Body(RefFace *from_ref_face, 02314 std::map< RefEntity*, RefEntity* > *old_to_new_map ) const 02315 { 02316 // Given the arguments, make a RefFace. 02317 RefFace* new_ref_face = this->make_RefFace(from_ref_face, 02318 old_to_new_map ); 02319 if (!new_ref_face) 02320 { 02321 return (Body *)NULL; 02322 } 02323 02324 DLIList<Body*> bodies; 02325 new_ref_face->bodies(bodies); 02326 02327 if (!bodies.size()) { 02328 GeometryEntity *ge_ptr = new_ref_face->get_geometry_entity_ptr(); 02329 Surface *surf_ptr = CAST_TO(ge_ptr, Surface); 02330 assert(surf_ptr != 0); 02331 02332 BodySM *body_sm = gmeList.get()->make_BodySM(surf_ptr); 02333 return GeometryQueryTool::instance()->make_Body(body_sm); 02334 } 02335 02336 else return bodies.get(); 02337 } 02338 //------------------------------------------------------------------------- 02339 // Purpose : This function takes a type information and a list of 02340 // RefEdges to create a Body that has just one RefFace. 02341 // The underlying representation of the Body is 02342 // determined by the GeometryModifyEngine of the 02343 // RefEdges. All the RefEdges in the list must be 02344 // associated with the same GeometryModifyEngine. The 02345 // return value can be a NULL pointer, if the Body cannot 02346 // be succesfully made for some reason. 02347 // 02348 // Special Notes : 02349 // 02350 // Creator : Raikanta Sahu 02351 // 02352 // Creation Date : 03/29/97 02353 //------------------------------------------------------------------------- 02354 02355 Body* GeometryModifyTool::make_Body(GeometryType ref_face_type, 02356 DLIList<RefEdge*>& ref_edge_list, 02357 RefFace *ref_face_ptr) const 02358 { 02359 if( CubitUndo::get_undo_enabled() ) 02360 CubitUndo::save_state_with_cubit_file( ref_edge_list ); 02361 02362 bool is_free_face = false; 02363 02364 // Given the arguments, make a RefFace. 02365 RefFace* new_ref_face = this->make_RefFace(ref_face_type, 02366 ref_edge_list, 02367 is_free_face, 02368 ref_face_ptr); 02369 02370 if( new_ref_face == NULL ) 02371 return NULL; 02372 02373 // If new_ref_face doesn't have a body, create one. 02374 DLIList<Body*> bodies; 02375 new_ref_face->bodies(bodies); 02376 02377 if (!bodies.size()) { 02378 Surface *surf_ptr = new_ref_face->get_surface_ptr(); 02379 assert(surf_ptr != 0); 02380 GeometryModifyEngine* engine = get_engine(surf_ptr); 02381 assert(engine != 0); 02382 02383 BodySM *body_sm = engine->make_BodySM(surf_ptr); 02384 Body* body = GeometryQueryTool::instance()->make_Body(body_sm); 02385 bodies.append( body ); 02386 } 02387 02388 if( CubitUndo::get_undo_enabled() ) 02389 { 02390 if( bodies.size() ) 02391 CubitUndo::note_result_entity( bodies.get() ); 02392 else 02393 CubitUndo::remove_last_undo(); 02394 } 02395 02396 // Return the body containing the new RefFace. 02397 return bodies.get(); 02398 } 02399 02400 //------------------------------------------------------------------------- 02401 // Purpose : The following functions copy the input Body to create 02402 // a new one. Some transformations may be applied to the 02403 // newly copied Body before returning it: 02404 // copy 02405 // copy_and_move 02406 // copy_and_rotate 02407 // 02408 // Special Notes : 02409 // 02410 // Creator : Malcolm J. Panthaki 02411 // 02412 // Creation Date : 10/1/96 02413 //------------------------------------------------------------------------- 02414 Body* GeometryModifyTool::copy_body ( Body* bodyPtr, 02415 std::map< RefEntity*, RefEntity* > *old_to_new_map ) 02416 { 02417 BodySM* body_sm = bodyPtr->get_body_sm_ptr(); 02418 if (!body_sm) 02419 { 02420 PRINT_ERROR("Body %d is invalid -- no attached BodySM.\n", bodyPtr->id()); 02421 return 0; 02422 } 02423 02424 //this list will get all the TB's what we'll be copying 02425 DLIList<RefEntity*> tmp_list; 02426 tmp_list.append( bodyPtr ); 02427 TopologyBridge *top_bridge; 02428 prepare_for_copy( bodyPtr, top_bridge ); 02429 02430 BodySM *tmp_body_sm = CAST_TO( top_bridge, BodySM ); 02431 02432 GeometryModifyEngine* GMEPtr = get_engine(tmp_body_sm); 02433 if ( GMEPtr == NULL ) 02434 { 02435 clean_up_from_copy_failure( top_bridge ); 02436 PRINT_ERROR("Cannot copy volume %d\n" 02437 " Copy is supported for bodies based on solid " 02438 "models only\n", bodyPtr->ref_volume()->id() ); 02439 return NULL ; 02440 } 02441 std::map<TopologyBridge*, TopologyBridge*> old_tb_to_new_tb; 02442 02443 BodySM *new_bodysm = GMEPtr->copy_body(tmp_body_sm, &old_tb_to_new_tb ); 02444 02445 if (!new_bodysm) 02446 { 02447 clean_up_from_copy_failure( top_bridge ); 02448 PRINT_ERROR("Failed to copy volume %d\n", bodyPtr->ref_volume()->id()); 02449 return 0; 02450 } 02451 02452 TopologyBridge *top_bridge_new = new_bodysm; 02453 finish_copy( top_bridge_new, body_sm ); 02454 02455 new_bodysm = CAST_TO( top_bridge_new, BodySM ); 02456 Body *body_new = GeometryQueryTool::instance()->make_Body(new_bodysm); 02457 02458 if( old_to_new_map ) 02459 create_old_to_new_ref_ent_map( body_sm, new_bodysm, *old_to_new_map, old_tb_to_new_tb ); 02460 02461 return body_new; 02462 } 02463 02464 //------------------------------------------------------------------------- 02465 // Purpose : Check if bodies can be webcut 02466 // 02467 // Special Notes : 02468 // 02469 // Creator : Jason Kraftcheck 02470 // 02471 // Creation Date : 10/10/03 02472 //------------------------------------------------------------------------- 02473 CubitStatus GeometryModifyTool::okay_to_modify( 02474 DLIList<Body*>& webcut_body_list, 02475 const char* op ) const 02476 { 02477 CubitStatus ret = CUBIT_SUCCESS; 02478 02479 Body *b = webcut_body_list.get(); 02480 if(b) 02481 { 02482 GeometryModifyEngine *gme = get_engine(b); 02483 if(gme) 02484 { 02485 if(!gme->supports_interoperability() && 02486 contains_intermediate_geom(webcut_body_list)) 02487 { 02488 PRINT_ERROR("Intermixing real and virtual geometry operations using the current solid modeling kernel is not allowed.\n"); 02489 ret = CUBIT_FAILURE; 02490 } 02491 } 02492 } 02493 02494 if(ret == CUBIT_SUCCESS) 02495 { 02496 // If the operation is not one of the ones below... 02497 if(strcmp(op, "WEBCUT") && 02498 strcmp(op, "CHOP") && 02499 strcmp(op, "UNITE") && 02500 strcmp(op, "TWEAK") && 02501 strcmp(op, "IMPRINT") && 02502 strcmp(op, "REGULARIZE") && 02503 strcmp(op, "SPLIT_SURFACE") && 02504 strcmp(op, "REMOVE_TOPOLOGY") && 02505 strcmp(op, "SPLIT") && 02506 strcmp(op, "NON_UNIFORM_SCALE")) 02507 { 02508 if (contains_intermediate_geom(webcut_body_list)) 02509 { 02510 PRINT_ERROR("Performing %s on volumes containing virtual geometry is not allowed.\n", op); 02511 ret = CUBIT_FAILURE; 02512 } 02513 } 02514 else 02515 { 02516 if(contains_partitions(webcut_body_list)) 02517 { 02518 PRINT_ERROR("Performing %s on volumes containing virtual partitions is not allowed.\n", op); 02519 ret = CUBIT_FAILURE; 02520 } 02521 } 02522 } 02523 02524 return ret; 02525 } 02526 02527 02528 //------------------------------------------------------------------------- 02529 // Purpose : Common code for finishing webcut operations. 02530 // 02531 // Special Notes : 02532 // 02533 // Creator : Jason Kraftcheck 02534 // 02535 // Creation Date : 09/25/03 02536 //------------------------------------------------------------------------- 02537 CubitStatus GeometryModifyTool::finish_webcut( DLIList<Body*>& webcut_body_list, 02538 DLIList<BodySM*>& result_body_sms, 02539 CubitBoolean merge, 02540 CubitStatus status, 02541 DLIList<Body*>& result_list, 02542 DLIList<int> *merged_surface_ids, 02543 DLIList<int> *merged_curve_ids, 02544 CubitBoolean print_info) const 02545 { 02546 if (!finish_sm_op(webcut_body_list, result_body_sms, result_list,(bool)print_info)) 02547 status = CUBIT_FAILURE; 02548 02549 DLIList<Body*> temp_result_list; 02550 if (status) 02551 { 02552 status = separate_body_after_webcut( result_list, temp_result_list); 02553 result_list = temp_result_list; 02554 } 02555 02556 if( merged_surface_ids && merged_curve_ids ) 02557 fixup_merged_entities( *merged_surface_ids, *merged_curve_ids ); 02558 02559 if (merge && status) 02560 { 02561 DLIList<Body*> temp_results(result_list); 02562 status = MergeTool::instance()->merge_bodies( temp_results ); 02563 } 02564 return status; 02565 } 02566 02567 02568 //------------------------------------------------------------------------- 02569 // Purpose : Complete solid modeling operation on bodies 02570 // 02571 // Special Notes : 02572 // 02573 // Creator : Jason Kraftcheck 02574 // 02575 // Creation Date : 09/25/03 02576 //------------------------------------------------------------------------- 02577 CubitStatus GeometryModifyTool::finish_sm_op( DLIList<Body*>& input_bodies, 02578 DLIList<BodySM*>& new_bodies, 02579 DLIList<Body*>& result_bodies, 02580 bool print_info ) const 02581 { 02582 int i; 02583 GeometryQueryTool* gqt = GeometryQueryTool::instance(); 02584 02585 DLIList<int> updated_ids, created_ids, destroyed_ids; 02586 DLIList<int> updated_vol_ids, created_vol_ids, destroyed_vol_ids; 02587 02588 // traverse the body object and remove any meshes from modified objects 02589 int b; 02590 for (b = 0; b < input_bodies.size(); b++) { 02591 Body* body = input_bodies.get_and_step(); 02592 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_ENTITY_MODIFIED, body)); 02593 } 02594 02595 // Remove dead bodies 02596 input_bodies.reset(); 02597 for (i = input_bodies.size(); i--;) 02598 { 02599 Body* body = input_bodies.step_and_get(); 02600 02601 BodySM* bodysm = body->get_body_sm_ptr(); 02602 if (!bodysm) 02603 { 02604 // If the body was destroyed, update the list 02605 destroyed_ids.append( body->id() ); 02606 02607 DLIList<RefVolume*> temp_vols; 02608 body->ref_volumes( temp_vols ); 02609 for( int nv = temp_vols.size(); nv > 0; nv-- ) 02610 { 02611 if( !temp_vols.get()->get_lump_ptr() ) 02612 destroyed_vol_ids.append( temp_vols.get_and_step()->id() ); 02613 } 02614 02615 input_bodies.change_to(0); 02616 gqt->destroy_dead_entity(body); 02617 } 02618 else 02619 { 02620 remove_dead_entity_names( body ); 02621 } 02622 } 02623 gqt->cleanout_deactivated_geometry(); 02624 02625 // Create new bodies 02626 new_bodies.last(); 02627 for (i = new_bodies.size(); i--; ) 02628 { 02629 BodySM* bodysm = new_bodies.step_and_get(); 02630 bool newbody = bodysm->owner() == 0; 02631 Body* body = gqt->make_Body(bodysm); 02632 result_bodies.append(body); 02633 02634 if (newbody) 02635 { 02636 created_ids.append(body->id()); 02637 02638 DLIList<RefVolume*> temp_vols; 02639 body->ref_volumes( temp_vols ); 02640 for( int nv = temp_vols.size(); nv > 0; nv-- ) 02641 { 02642 created_vol_ids.append( temp_vols.get_and_step()->id() ); 02643 } 02644 } 02645 else 02646 { 02647 updated_ids.append(body->id()); 02648 02649 DLIList<RefVolume*> temp_vols; 02650 body->ref_volumes( temp_vols ); 02651 for( int nv = temp_vols.size(); nv > 0; nv-- ) 02652 { 02653 updated_vol_ids.append( temp_vols.get_and_step()->id() ); 02654 } 02655 } 02656 } 02657 gqt->cleanout_deactivated_geometry(); 02658 02659 if (print_info) 02660 { 02661 if( DEBUG_FLAG( 153 ) ) 02662 { 02663 if (created_ids.size()) 02664 CubitUtil::list_entity_ids( "Created body(s): ", created_ids ); 02665 if (updated_ids.size()) 02666 CubitUtil::list_entity_ids( "Updated body(s): ", updated_ids ); 02667 if (destroyed_ids.size()) 02668 CubitUtil::list_entity_ids( "Destroyed body(s): ", destroyed_ids ); 02669 } 02670 02671 if (created_vol_ids.size()) 02672 CubitUtil::list_entity_ids( "Created volume(s): ", created_vol_ids ); 02673 if (updated_vol_ids.size()) 02674 CubitUtil::list_entity_ids( "Updated volume(s): ", updated_vol_ids ); 02675 if (destroyed_vol_ids.size()) 02676 CubitUtil::list_entity_ids( "Destroyed volume(s): ", destroyed_vol_ids ); 02677 } 02678 02679 return CUBIT_SUCCESS; 02680 } 02681 02682 02683 02684 //------------------------------------------------------------------------- 02685 // Purpose : Webcut a body with a cylinder given the input parameters. 02686 // Special Notes : 02687 // 02688 // Creator : David White 02689 // 02690 // Creation Date : 10/28/97 02691 //------------------------------------------------------------------------- 02692 CubitStatus GeometryModifyTool::webcut_with_cylinder( 02693 DLIList<Body*>& webcut_body_list, 02694 double radius, 02695 const CubitVector &axis, 02696 const CubitVector ¢er, 02697 DLIList<Body*>& results_list, 02698 DLIList<Body*> &neighboring_bodies, 02699 ImprintType imprint_type, 02700 CubitBoolean merge, 02701 CubitBoolean preview) 02702 { 02703 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 02704 return CUBIT_FAILURE; 02705 02706 GfxPreview::clear(); 02707 02708 CubitStatus rval = CUBIT_SUCCESS; 02709 02710 if (preview) 02711 { 02712 // find the bounding box for the cylinder 02713 CubitBox bounding_box; 02714 Body* body_ptr = webcut_body_list.get_and_step(); 02715 bounding_box = body_ptr->bounding_box(); 02716 02717 int i; 02718 for( i=1; i<webcut_body_list.size(); i++ ) 02719 { 02720 body_ptr = webcut_body_list.get_and_step(); 02721 bounding_box |= body_ptr->bounding_box(); 02722 } 02723 02724 int color = CUBIT_BLUE_INDEX; 02725 GfxPreview::draw_cylinder(axis, center, bounding_box, (float) radius, color); 02726 GfxPreview::flush(); 02727 return rval; 02728 } 02729 02730 if( CubitUndo::get_undo_enabled() ) 02731 { 02732 DLIList<Body*> bodies_to_save; 02733 bodies_to_save += webcut_body_list; 02734 bodies_to_save += neighboring_bodies; 02735 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 02736 } 02737 02738 const int count = webcut_body_list.size(); 02739 DLIList<BodySM*> result_sm_list; 02740 DLIList<Body*> body_list(webcut_body_list); 02741 DLIList<BodySM*> engine_body_sms(count); 02742 DLIList<Body*> engine_bodies(count); 02743 GeometryModifyEngine* gme = 0; 02744 02745 if(!preview) 02746 do_attribute_setup(); 02747 02748 while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) ) 02749 { 02750 //get all bodysms that we might modify in this operation 02751 DLIList<BodySM*> neighbor_imprint_list; 02752 DLIList<BodySM*> bodies_sm_to_modify; 02753 DLIList<Body*> bodies_to_modify; 02754 bodies_to_modify += engine_bodies; 02755 int i; 02756 for( i=neighboring_bodies.size(); i--; ) 02757 { 02758 Body *tmp_body = neighboring_bodies.get_and_step(); 02759 BodySM *tmp_body_sm = tmp_body->get_body_sm_ptr(); 02760 if( gme == get_engine(tmp_body_sm ) ) 02761 { 02762 neighbor_imprint_list.append( tmp_body_sm ); 02763 bodies_to_modify.append( tmp_body ); 02764 } 02765 } 02766 02767 DLIList<int> merged_surface_ids; 02768 DLIList<int> merged_curve_ids; 02769 02770 if(!preview) 02771 { 02772 bodies_sm_to_modify += neighbor_imprint_list; 02773 02774 push_attributes_before_modify( bodies_sm_to_modify ); 02775 //get all the child entities that have been merged 02776 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 02777 } 02778 02779 // note that preview actually gets handled before this point 02780 CubitStatus status = webcut_w_cylinder(engine_body_sms, radius, axis, 02781 center, neighbor_imprint_list, result_sm_list, imprint_type ); 02782 02783 if ( status != CUBIT_FAILURE ) 02784 { 02785 if(!preview) 02786 { 02787 restore_vg_after_modify(result_sm_list, bodies_to_modify, gme); 02788 remove_pushed_attributes(result_sm_list, bodies_to_modify); 02789 } 02790 status = finish_webcut( engine_bodies, result_sm_list, merge, status, 02791 results_list, &merged_surface_ids, &merged_curve_ids ); 02792 } 02793 else 02794 { 02795 if(!preview) 02796 remove_pushed_attributes(result_sm_list, engine_bodies); 02797 } 02798 02799 02800 engine_bodies.clean_out(); 02801 engine_body_sms.clean_out(); 02802 result_sm_list.clean_out(); 02803 02804 if ( status == CUBIT_FAILURE ) 02805 { 02806 rval = CUBIT_FAILURE; 02807 break; 02808 } 02809 } 02810 02811 if(!preview) 02812 do_attribute_cleanup(); 02813 02814 if( CubitUndo::get_undo_enabled() ) 02815 { 02816 if( rval == CUBIT_SUCCESS ) 02817 CubitUndo::note_result_bodies( results_list ); 02818 else 02819 CubitUndo::remove_last_undo(); 02820 } 02821 02822 return rval; 02823 } 02824 //************************************************************************************************************************************* 02825 //------------------------------------------------------------------------- 02826 // Purpose : Webcut a body with a cone given the input parameters. 02827 // Special Notes : 02828 // 02829 // Creator : Ajoy 02830 // 02831 // Creation Date : 04/23/2012 02832 //------------------------------------------------------------------------- 02833 CubitStatus GeometryModifyTool::webcut_with_Cone( 02834 DLIList<Body*>& webcut_body_list, 02835 DLIList<BodySM*> &webcut_bodySM_list, 02836 double outer_radius,double inner_radius, 02837 CubitVector& AxisPt1, 02838 CubitVector& AxisPt2, 02839 DLIList<Body*>& results_list, 02840 DLIList<Body*> &neighboring_bodies, 02841 ImprintType imprint_type, 02842 CubitBoolean merge, 02843 CubitBoolean preview) 02844 { 02845 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 02846 return CUBIT_FAILURE; 02847 02848 CubitStatus rval = CUBIT_SUCCESS; 02849 02850 02851 GfxPreview::clear(); 02852 02853 02854 // find the height 02855 double dHeight = sqrt( (AxisPt2.x()-AxisPt1.x()) * (AxisPt2.x()-AxisPt1.x())+ 02856 (AxisPt2.y()-AxisPt1.y()) * (AxisPt2.y()-AxisPt1.y())+ 02857 (AxisPt2.z()-AxisPt1.z()) * (AxisPt2.z()-AxisPt1.z()) ); 02858 02859 // Find the Tan Angle 02860 double Diff = fabs(outer_radius - inner_radius); 02861 Diff /= dHeight; 02862 double dTanAngle = atan ( Diff ) ; 02863 02864 if (preview) 02865 { 02866 // find the bounding box for the cylinder 02867 CubitBox bounding_box; 02868 Body* body_ptr = webcut_body_list.get_and_step(); 02869 bounding_box = body_ptr->bounding_box(); 02870 02871 int i; 02872 for( i=1; i<webcut_body_list.size(); i++ ) 02873 { 02874 body_ptr = webcut_body_list.get_and_step(); 02875 bounding_box |= body_ptr->bounding_box(); 02876 } 02877 02878 CubitVector axis; 02879 axis.x( AxisPt2.x()-AxisPt1.x() ); axis.y( AxisPt2.y()-AxisPt1.y() ); 02880 axis.z( AxisPt2.z()-AxisPt1.z() ); 02881 02882 02883 CubitVector start; 02884 CubitVector end; 02885 double dExtendedOuterRadius; 02886 double dExtendedInnerRadius; 02887 02888 02889 // Now extend the 2 end points to extend beyond the BBox limits. In case it converges, stop at the Apex. 02890 02891 FindExtendedPoints( AxisPt1 , AxisPt2 , outer_radius , inner_radius , axis, dHeight , bounding_box , 02892 dTanAngle, start , end, dExtendedOuterRadius , dExtendedInnerRadius ); 02893 02894 int color = CUBIT_BLUE_INDEX; 02895 GfxPreview::draw_frustum(axis, start, end, dExtendedOuterRadius, dExtendedInnerRadius ,bounding_box , color); 02896 GfxPreview::flush(); 02897 return rval; 02898 } 02899 02900 if( CubitUndo::get_undo_enabled() ) 02901 { 02902 DLIList<Body*> bodies_to_save; 02903 bodies_to_save += webcut_body_list; 02904 bodies_to_save += neighboring_bodies; 02905 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 02906 } 02907 02908 const int count = webcut_body_list.size(); 02909 DLIList<BodySM*> result_sm_list; 02910 DLIList<Body*> body_list(webcut_body_list); 02911 DLIList<BodySM*> engine_body_sms(count); 02912 DLIList<Body*> engine_bodies(count); 02913 GeometryModifyEngine* gme = 0; 02914 02915 if(!preview) 02916 do_attribute_setup(); 02917 02918 while ( (gme = group_bodies_by_engine(webcut_body_list, engine_bodies, engine_body_sms)) ) 02919 { 02920 //get all bodysms that we might modify in this operation 02921 DLIList<BodySM*> neighbor_imprint_list; 02922 DLIList<BodySM*> bodies_sm_to_modify; 02923 DLIList<Body*> bodies_to_modify; 02924 bodies_to_modify += engine_bodies; 02925 int i; 02926 for( i=neighboring_bodies.size(); i--; ) 02927 { 02928 Body *tmp_body = neighboring_bodies.get_and_step(); 02929 BodySM *tmp_body_sm = tmp_body->get_body_sm_ptr(); 02930 if( gme == get_engine(tmp_body_sm ) ) 02931 { 02932 neighbor_imprint_list.append( tmp_body_sm ); 02933 bodies_to_modify.append( tmp_body ); 02934 } 02935 } 02936 02937 02938 DLIList<BodySM*> Body_to_Cut_SM; 02939 02940 for( i = 0 ;i<webcut_body_list.size(); i++ ) 02941 { 02942 Body* body = webcut_body_list.get_and_step(); 02943 BodySM *Body_To_Cut = body->get_body_sm_ptr(); 02944 02945 Body_to_Cut_SM.append( Body_To_Cut ) ; 02946 } 02947 02948 02949 02950 DLIList<int> merged_surface_ids; 02951 DLIList<int> merged_curve_ids; 02952 02953 if(!preview) 02954 { 02955 bodies_sm_to_modify += neighbor_imprint_list; 02956 02957 push_attributes_before_modify( bodies_sm_to_modify ); 02958 //get all the child entities that have been merged 02959 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 02960 } 02961 02962 02963 // Get the overall bounding box of the bodies list 02964 Body* body_ptr = NULL; 02965 CubitBox bounding_box; 02966 if(body_list.size()) 02967 { 02968 body_ptr = body_list.get_and_step(); 02969 bounding_box = body_ptr->bounding_box(); 02970 for( i=1; i<webcut_body_list.size(); i++ ) 02971 { 02972 body_ptr = body_list.get_and_step(); 02973 bounding_box |= body_ptr->bounding_box(); 02974 } 02975 } 02976 02977 02978 02979 // Get the Geometry engine 02980 GeometryModifyEngine* gme = 02981 GeometryModifyTool::instance()->get_engine( body_ptr ); 02982 02983 02985 //CubitStatus status = CreateCircularBody(webcut_body_list ); 02986 02987 CubitStatus status = CUBIT_SUCCESS; 02988 02989 02990 CubitVector axis; 02991 axis.x( AxisPt2.x()-AxisPt1.x() ); axis.y( AxisPt2.y()-AxisPt1.y() ); 02992 axis.z( AxisPt2.z()-AxisPt1.z() ); 02993 02994 02995 02996 02997 // Set The important deciders. 02998 02999 bool bIfReverseAxis = false; 03000 if( outer_radius < inner_radius ) 03001 { 03002 bIfReverseAxis = true; 03003 } 03004 03005 03006 //**************************************// 03007 // find the extension of the narrow end. 03008 //**************************************// 03009 03010 // For this find the extended end point, at the smaller end 03011 // and assign zero radius, setting that point to be the AxisPt2. 03012 03013 // Will be done only if outerRad is bigger than innerRad 03014 // Else set a bool to remember that, the inner_radius is set as the outer. 03015 03016 CubitVector endpt ; 03017 if( outer_radius > inner_radius ) 03018 { 03019 //EndPt = FindExtendedEndPt( outer_radius , inner_radius , AxisPt2 , axis, dHeight ); 03020 03021 03022 double Diff = (outer_radius - inner_radius); 03023 Diff /= dHeight; 03024 double dAngle = atan ( Diff ) ; 03025 axis.normalize(); 03026 03027 double dTan = tan( dAngle ); 03028 double dExtendvalue = inner_radius / dTan; 03029 03030 endpt.x( ( axis.x() * dExtendvalue ) + AxisPt2.x() ); 03031 endpt.y( ( axis.y() * dExtendvalue ) + AxisPt2.y() ); 03032 endpt.z( ( axis.z() * dExtendvalue ) + AxisPt2.z() ); 03033 03034 03035 03036 dHeight = sqrt( (endpt.x() - AxisPt1.x()) * (endpt.x() - AxisPt1.x())+ 03037 (endpt.y() - AxisPt1.y()) * (endpt.y() - AxisPt1.y())+ 03038 (endpt.z() - AxisPt1.z()) * (endpt.z() - AxisPt1.z()) ); 03039 03040 AxisPt2.x( endpt.x() ); 03041 AxisPt2.y( endpt.y() ); 03042 AxisPt2.z( endpt.z() ); 03043 } 03044 else 03045 { 03046 // reverse the axis. 03047 03048 axis.x( -axis.x()); 03049 axis.y( -axis.y()); 03050 axis.z( -axis.z()); 03051 03052 //endpt = FindExtendedendpt( inner_radius , outer_radius , AxisPt1 , axis, dHeight ); 03053 03054 03055 double Diff = (inner_radius - outer_radius); 03056 Diff /= dHeight; 03057 double dAngle = atan ( Diff ) ; 03058 axis.normalize(); 03059 03060 double dTan = tan( dAngle ); 03061 double dExtendvalue = outer_radius / dTan; 03062 03063 endpt.x( ( axis.x() * dExtendvalue ) + AxisPt1.x() ); 03064 endpt.y( ( axis.y() * dExtendvalue ) + AxisPt1.y() ); 03065 endpt.z( ( axis.z() * dExtendvalue ) + AxisPt1.z() ); 03066 03067 03068 03069 03070 dHeight = sqrt( (endpt.x() - AxisPt2.x()) * (endpt.x() - AxisPt2.x())+ 03071 (endpt.y() - AxisPt2.y()) * (endpt.y() - AxisPt2.y())+ 03072 (endpt.z() - AxisPt2.z()) * (endpt.z() - AxisPt2.z()) ); 03073 03074 AxisPt1.x( endpt.x() ); 03075 AxisPt1.y( endpt.y() ); 03076 AxisPt1.z( endpt.z() ); 03077 03078 // reset the axis. 03079 03080 axis.x( -axis.x()); 03081 axis.y( -axis.y()); 03082 axis.z( -axis.z()); 03083 03084 } 03085 03086 03087 03088 //*****************************************// 03089 // Now find the extension of the bigger end. 03090 //*****************************************// 03091 03092 //CubitVector EndPt ; 03093 double dExtendedRadius; 03094 if( outer_radius > inner_radius ) 03095 { 03096 // reverse the axis. 03097 axis.x( -axis.x()); 03098 axis.y( -axis.y()); 03099 axis.z( -axis.z()); 03100 03101 03102 //EndPt = FindExtendedStartPt( bounding_box , outer_radius , inner_radius , AxisPt1 , axis, dHeight , dTanAngle , dExtendedRadius ); 03103 03104 03105 03106 CubitVector Extended_Start_Pt; 03107 03108 // Find the Difference between the Max and thre min values in all 3 directions. 03109 // Incase the point is within the box limits, then add the difference values 03110 // in all 3 directions , witht he " Axis " as the direction vector and extend the point. 03111 03112 // After that find the Radius of this bigger end. 03113 03114 CubitVector DiffVec; 03115 03116 axis.normalize(); 03117 03118 DiffVec.x( fabs( bounding_box.max_x() - bounding_box.min_x() )); 03119 DiffVec.y( fabs( bounding_box.max_y() - bounding_box.min_y() )); 03120 DiffVec.z( fabs( bounding_box.max_z() - bounding_box.min_z() )); 03121 03122 // Extend the start Pt 03123 03124 Extended_Start_Pt.x( AxisPt1.x() + ( axis.x() * DiffVec.x() ) ); 03125 Extended_Start_Pt.y( AxisPt1.y() + ( axis.y() * DiffVec.y() ) ); 03126 Extended_Start_Pt.z( AxisPt1.z() + ( axis.z() * DiffVec.z() ) ); 03127 03128 03129 // Find the length 03130 03131 double dLength = sqrt( (( AxisPt1.x() - Extended_Start_Pt.x()) * (AxisPt1.x() - Extended_Start_Pt.x()) ) + 03132 (( AxisPt1.y() - Extended_Start_Pt.y()) * (AxisPt1.y() - Extended_Start_Pt.y()) ) + 03133 (( AxisPt1.z() - Extended_Start_Pt.z()) * (AxisPt1.z() - Extended_Start_Pt.z()) ) ); 03134 03135 03136 03137 // Find the Extended Radius 03138 03139 dExtendedRadius = outer_radius + ( tan( dTanAngle ) * dLength ) ; 03140 03141 03142 dHeight = sqrt( (Extended_Start_Pt.x() - AxisPt2.x()) * (Extended_Start_Pt.x() - AxisPt2.x())+ 03143 (Extended_Start_Pt.y() - AxisPt2.y()) * (Extended_Start_Pt.y() - AxisPt2.y())+ 03144 (Extended_Start_Pt.z() - AxisPt2.z()) * (Extended_Start_Pt.z() - AxisPt2.z()) ); 03145 03146 if( dExtendedRadius == 0 ) 03147 dExtendedRadius = outer_radius; 03148 03149 AxisPt1.x( Extended_Start_Pt.x() ); 03150 AxisPt1.y( Extended_Start_Pt.y() ); 03151 AxisPt1.z( Extended_Start_Pt.z() ); 03152 03153 // reverse the axis. 03154 axis.x( -axis.x()); 03155 axis.y( -axis.y()); 03156 axis.z( -axis.z()); 03157 03158 } 03159 else 03160 { 03161 //EndPt = FindExtendedStartPt( bounding_box , inner_radius , outer_radius , AxisPt2 , axis, dHeight , dTanAngle , dExtendedRadius ); 03162 03163 03164 03165 03166 CubitVector Extended_Start_Pt; 03167 03168 // Find the Difference between the Max and thre min values in all 3 directions. 03169 // Incase the point is within the box limits, then add the difference values 03170 // in all 3 directions , witht he " Axis " as the direction vector and extend the point. 03171 03172 // After that find the Radius of this bigger end. 03173 03174 CubitVector DiffVec; 03175 03176 axis.normalize(); 03177 03178 DiffVec.x( fabs( bounding_box.max_x() - bounding_box.min_x() )); 03179 DiffVec.y( fabs( bounding_box.max_y() - bounding_box.min_y() )); 03180 DiffVec.z( fabs( bounding_box.max_z() - bounding_box.min_z() )); 03181 03182 // Extend the start Pt 03183 03184 Extended_Start_Pt.x( AxisPt2.x() + ( axis.x() * DiffVec.x() ) ); 03185 Extended_Start_Pt.y( AxisPt2.y() + ( axis.y() * DiffVec.y() ) ); 03186 Extended_Start_Pt.z( AxisPt2.z() + ( axis.z() * DiffVec.z() ) ); 03187 03188 03189 // Find the length 03190 03191 double dLength = sqrt( (( AxisPt2.x() - Extended_Start_Pt.x()) * (AxisPt2.x() - Extended_Start_Pt.x()) ) + 03192 (( AxisPt2.y() - Extended_Start_Pt.y()) * (AxisPt2.y() - Extended_Start_Pt.y()) ) + 03193 (( AxisPt2.z() - Extended_Start_Pt.z()) * (AxisPt2.z() - Extended_Start_Pt.z()) ) ); 03194 03195 03196 03197 // Find the Extended Radius 03198 03199 dExtendedRadius = inner_radius + ( tan( dTanAngle ) * dLength ) ; 03200 03201 03202 dHeight = sqrt( (Extended_Start_Pt.x() - AxisPt1.x()) * (Extended_Start_Pt.x() - AxisPt1.x())+ 03203 (Extended_Start_Pt.y() - AxisPt1.y()) * (Extended_Start_Pt.y() - AxisPt1.y())+ 03204 (Extended_Start_Pt.z() - AxisPt1.z()) * (Extended_Start_Pt.z() - AxisPt1.z()) ); 03205 03206 AxisPt2.x( Extended_Start_Pt.x() ); 03207 AxisPt2.y( Extended_Start_Pt.y() ); 03208 AxisPt2.z( Extended_Start_Pt.z() ); 03209 03210 if( dExtendedRadius == 0 ) 03211 dExtendedRadius = outer_radius; 03212 03213 } 03214 03215 03216 03217 //Create the cylinder 03218 03219 BodySM* bodySM_Ptr = NULL; 03220 outer_radius = dExtendedRadius; 03221 inner_radius = 0; 03222 bodySM_Ptr = gmeList.get()->cylinder( dHeight, outer_radius, outer_radius, inner_radius ); 03223 03224 03225 if( !bodySM_Ptr ) 03226 { 03227 return CUBIT_FAILURE; 03228 } 03229 03230 03231 DLIList<Curve*> curve_list; 03232 03233 bodySM_Ptr->curves(curve_list); 03234 03235 // infor for the Frustum Axis 03236 03237 CubitVector Frustum_Axis; 03238 03239 Frustum_Axis.x(0); 03240 Frustum_Axis.y(0); 03241 Frustum_Axis.z(dHeight); 03242 03243 03244 03245 03246 if( bIfReverseAxis ) 03247 axis.z( -axis.z() ); 03248 03249 03250 // Get Cross product for the resultant vector, which will be the axis for rotation 03251 CubitVector cross; 03252 cross = Frustum_Axis * axis; 03253 03254 03255 // 2. Find the Angle Between them 03256 CubitVector Angle; 03257 double dAngle = Angle.vector_angle( Frustum_Axis , axis ); 03258 03259 03260 03261 //Now find the angle and the axis to rotate about... 03262 03263 dAngle = 180.0*dAngle/CUBIT_PI; 03264 03265 if( bIfReverseAxis ) 03266 dAngle = 360 - dAngle ; 03267 03268 03269 03270 // 3. Rotate the body for the received cross product axis ( cross ) as the axis 03271 // and for the angle, dAngle 03272 //GeometryQueryTool::instance()->rotate( cutting_tool_ptr , cross , dAngle ); 03273 03274 GeometryQueryEngine* engine = bodySM_Ptr->get_geometry_query_engine(); 03275 CubitStatus result = engine->rotate( bodySM_Ptr, cross, dAngle ); 03276 03277 03278 // 4. Now find the mid-point of the specified 2 vertices, and assign that as the 03279 // 2'nd parameter, for the Pt at which the center of the, created frustum should lie. 03280 03281 CubitVector Pt; 03282 Pt.x( (AxisPt1.x() + AxisPt2.x() )/2 ); 03283 Pt.y( (AxisPt1.y() + AxisPt2.y() )/2 ); 03284 Pt.z( (AxisPt1.z() + AxisPt2.z() )/2 ); 03285 03286 03287 03288 // 5 . Now move the body to the location of the target_center. 03289 03290 CubitTransformMatrix xform; 03291 xform.translate( Pt ); 03292 result = engine->translate( bodySM_Ptr, Pt ); 03293 03294 03295 03296 03297 if (!result ) 03298 { 03299 if(!preview) 03300 { 03301 restore_vg_after_modify(result_sm_list, bodies_to_modify, gme); 03302 remove_pushed_attributes(result_sm_list, bodies_to_modify); 03303 } 03304 status = finish_webcut( engine_bodies, result_sm_list, merge, status, 03305 results_list, &merged_surface_ids, &merged_curve_ids ); 03306 } 03307 else 03308 { 03309 if(!preview) 03310 remove_pushed_attributes(result_sm_list, engine_bodies); 03311 } 03312 03313 if ( !result ) 03314 { 03315 rval = CUBIT_FAILURE; 03316 engine_bodies.clean_out(); 03317 engine_body_sms.clean_out(); 03318 result_sm_list.clean_out(); 03319 return rval; 03320 } 03321 03322 DLIList<BodySM*> results_list_SM; 03323 DLIList<BodySM*> neighboring_bodies_SM; 03324 // Use the BODY to perform webcut 03325 rval = gme->webcut(engine_body_sms, bodySM_Ptr, 03326 neighboring_bodies_SM, results_list_SM, imprint_type, preview ); 03327 03328 if( GeometryQueryTool::instance()->history().is_tracking() ) 03329 { 03330 if( rval == CUBIT_SUCCESS ) 03331 { 03332 gme->get_gqe()->delete_solid_model_entities(bodySM_Ptr); 03333 } 03334 } 03335 03336 // if we're doing the real thing (not preview) finish the process 03337 if (!preview) 03338 { 03339 restore_vg_after_modify(results_list_SM, body_list, gme); 03340 remove_pushed_attributes(results_list_SM, body_list); 03341 rval = finish_webcut( bodies_to_modify, results_list_SM, merge, 03342 rval, results_list); 03343 do_attribute_cleanup(); 03344 03345 //GeometryQueryTool::instance()->delete_Body( cutting_tool_ptr ); 03346 GeometryQueryEngine* gqe = bodySM_Ptr->get_geometry_query_engine(); 03347 gqe->delete_solid_model_entities(bodySM_Ptr); 03348 } 03349 03350 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 03351 { 03352 if( rval == CUBIT_SUCCESS ) 03353 CubitUndo::note_result_bodies( results_list ); 03354 else 03355 CubitUndo::remove_last_undo(); 03356 } 03357 03358 engine_bodies.clean_out(); 03359 engine_body_sms.clean_out(); 03360 result_sm_list.clean_out(); 03361 } 03362 return rval; 03363 } 03364 //************************************************************************************************************************************************************ 03365 void GeometryModifyTool::do_attribute_setup(void) 03366 { 03367 //save attribute settings 03368 CGMApp::instance()->save_current_attribute_states(); 03369 03370 //Turn off all attributes 03371 CubitAttribManager *attrib_manager = CGMApp::instance()->attrib_manager(); 03372 attrib_manager->set_all_auto_update_flags( CUBIT_FALSE ); 03373 attrib_manager->set_all_auto_actuate_flags( CUBIT_FALSE ); 03374 attrib_manager->set_all_auto_write_flags( CUBIT_FALSE ); 03375 attrib_manager->set_all_auto_read_flags( CUBIT_FALSE ); 03376 03377 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_ENTITY_NAME, CUBIT_TRUE); 03378 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_ENTITY_NAME, CUBIT_TRUE); 03379 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_ENTITY_NAME, CUBIT_TRUE); 03380 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_ENTITY_NAME, CUBIT_TRUE); 03381 03382 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_MESH_OUTPUT_GROUP, CUBIT_TRUE); 03383 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_MESH_OUTPUT_GROUP, CUBIT_TRUE); 03384 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_MESH_OUTPUT_GROUP, CUBIT_TRUE); 03385 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_MESH_OUTPUT_GROUP, CUBIT_TRUE); 03386 03387 03388 // enable update, actuate, write, read for composite attributes 03389 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_COMPOSITE_VG, CUBIT_TRUE); 03390 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_COMPOSITE_VG, CUBIT_TRUE); 03391 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_COMPOSITE_VG, CUBIT_TRUE); 03392 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_COMPOSITE_VG, CUBIT_TRUE); 03393 // enable update, actuate, write, read for partition attributes 03394 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_PARTITION_VG, CUBIT_TRUE); 03395 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_PARTITION_VG, CUBIT_TRUE); 03396 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_PARTITION_VG, CUBIT_TRUE); 03397 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_PARTITION_VG, CUBIT_TRUE); 03398 // enable update, actuate, write, read for entity ids 03399 // We will use these ID atts to make sure the ref entities associated with unmodified 03400 // virtual bridges will maintain the same ids after real operations. 03401 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_ENTITY_ID, CUBIT_TRUE); 03402 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_ENTITY_ID, CUBIT_TRUE); 03403 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_ENTITY_ID, CUBIT_TRUE); 03404 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_ENTITY_ID, CUBIT_TRUE); 03405 // enable metadata attributes 03406 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_ASSEMBLY_DATA, CUBIT_TRUE); 03407 CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_ASSEMBLY_DATA, CUBIT_TRUE); 03408 CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_ASSEMBLY_DATA, CUBIT_TRUE); 03409 CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_ASSEMBLY_DATA, CUBIT_TRUE); 03410 } 03411 03412 void GeometryModifyTool::do_attribute_cleanup(void) 03413 { 03414 03415 CGMApp::instance()->restore_previous_attribute_states(); 03416 } 03417 03418 // Pushes virtual geometry and boundary condition 03419 //attributes down to the underlying solid model topology 03420 void GeometryModifyTool::push_attributes_before_modify(DLIList<BodySM*> &old_sms) 03421 { 03422 // Get all of the ref entities involved and push CA_ENTITY_ID attributes 03423 // on to them. This will help us maintain ids on virtual that doesn't 03424 // get modified by the real operation. 03425 int i; 03426 DLIList<RefVolume*> volume_list; 03427 03428 for(i=old_sms.size(); i--;) 03429 { 03430 BodySM *bsm = old_sms.get_and_step(); 03431 Body *body = dynamic_cast<Body*>(bsm->topology_entity()); 03432 if(body) 03433 { 03434 // Append to the total list of volumes. 03435 body->ref_volumes(volume_list); 03436 } 03437 } 03438 // get all child entities (only get entities below volumes) 03439 DLIList<RefEntity*> child_list, ref_ent_list; 03440 CAST_LIST_TO_PARENT(volume_list, ref_ent_list); 03441 RefEntity::get_all_child_ref_entities( ref_ent_list, child_list ); 03442 03443 //by including the volumes we can propagate the bcs on them 03444 //across webcuts 03445 child_list+=ref_ent_list; 03446 03447 03448 // Only push the id attributes if we are doing persistent ids. 03449 if(!get_new_ids()) 03450 CubitAttribUser::auto_update_cubit_attrib(child_list); 03451 03452 DLIList<TopologyBridge*> top_bridges; 03453 CAST_LIST_TO_PARENT(old_sms, top_bridges); 03454 GeometryQueryTool::instance()->ige_export_geom(top_bridges); 03455 } 03456 03457 // Push imprint specific attributes down to the underlying solid model 03458 // topology prior to imprinting. 03459 void GeometryModifyTool::push_imprint_attributes_before_modify(DLIList<BodySM*> &body_sms) 03460 { 03461 GeometryQueryTool::instance()->ige_push_imprint_attributes_before_modify(body_sms); 03462 } 03463 03464 void GeometryModifyTool::push_named_attributes_to_curves_and_points(DLIList<TopologyBridge*> &tb_list, 03465 const char *name_in) 03466 { 03467 GeometryQueryTool::instance()->ige_push_named_attributes_to_curves_and_points(tb_list, name_in); 03468 } 03469 03470 // Cleanup imprint attributes that were pushed onto the underlying solid 03471 // model topology. 03472 void GeometryModifyTool::remove_imprint_attributes_after_modify(DLIList<BodySM*> &old_sms, 03473 DLIList<BodySM*> &new_sms) 03474 { 03475 GeometryQueryTool::instance()->ige_remove_imprint_attributes_after_modify(old_sms, new_sms); 03476 } 03477 03478 #ifdef CAT 03479 CubitStatus GeometryModifyTool::webcut_across_translate( 03480 DLIList<Body*> &webcut_body_list, 03481 RefFace *ref_face_top, 03482 RefFace *ref_face_bottom, 03483 DLIList<Body*> &results_list, 03484 ImprintType imprint_type, 03485 CubitBoolean merge, 03486 CubitBoolean preview) 03487 { 03488 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 03489 return CUBIT_FAILURE; 03490 03491 DLIList<Body*> original_body_list = webcut_body_list; 03492 const int count = webcut_body_list.size() + 2; 03493 DLIList<TopologyEntity*> entity_list(count); 03494 DLIList<TopologyBridge*> bridge_list(count); 03495 CAST_LIST_TO_PARENT(webcut_body_list, entity_list); 03496 entity_list.append( ref_face_top ); 03497 entity_list.append( ref_face_bottom ); 03498 GeometryModifyEngine* gme = common_modify_engine( entity_list, bridge_list ); 03499 03500 if ( !gme ) 03501 { 03502 PRINT_ERROR("Performing WEBCUTS on volumes containing geometry from\n" 03503 "different modeling engines is not allowed.\n" 03504 "Delete uncommon geometry on these volumes before operation.\n\n"); 03505 return CUBIT_FAILURE; 03506 } 03507 03508 Surface* surface_bottom = dynamic_cast<Surface*>(bridge_list.pop()); 03509 Surface* surface_top = dynamic_cast<Surface*>(bridge_list.pop()); 03510 DLIList<BodySM*> result_sm_list, webcut_sm_list(bridge_list.size()); 03511 CAST_LIST(bridge_list, webcut_sm_list, BodySM); 03512 03513 if (!preview) 03514 { 03515 do_attribute_setup(); 03516 push_attributes_before_modify(webcut_sm_list); 03517 } 03518 03519 DLIList<BodySM*> neighbor_list; 03520 CubitStatus result_val = gme->webcut_across_translate ( 03521 webcut_sm_list, surface_top, surface_bottom, result_sm_list, neighbor_list, imprint_type, preview ); 03522 03523 // if we're doing the real thing (not preview) finish the process 03524 if (!preview) 03525 { 03526 restore_vg_after_modify(result_sm_list, original_body_list, gme); 03527 remove_pushed_attributes(result_sm_list, original_body_list); 03528 result_val = finish_webcut( webcut_body_list, result_sm_list, merge, 03529 result_val, results_list); 03530 do_attribute_cleanup(); 03531 } 03532 03533 return result_val; 03534 } 03535 #endif 03536 03537 //------------------------------------------------------------------------- 03538 // Purpose : This functions webcuts a list of bodies using a loop 03539 // of curves 03540 // 03541 // Special Notes : 03542 // 03543 // Creator : Eric W. Nielsen 03544 // 03545 // Creation Date : 12/20/99 03546 //------------------------------------------------------------------------- 03547 CubitStatus GeometryModifyTool::webcut_with_curve_loop( 03548 DLIList<Body*>& webcut_body_list, 03549 DLIList<RefEdge*>& refedge_list, 03550 DLIList<Body*>& results_list, 03551 DLIList<Body*> &neighboring_bodies, 03552 ImprintType imprint_type, 03553 CubitBoolean merge, 03554 CubitBoolean preview) 03555 03556 { 03557 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 03558 return CUBIT_FAILURE; 03559 03560 GfxPreview::clear(); 03561 03562 int i; 03563 const int count = webcut_body_list.size() + refedge_list.size(); 03564 DLIList<TopologyEntity*> entity_list(count); 03565 DLIList<TopologyBridge*> bridge_list(count); 03566 CAST_LIST_TO_PARENT(webcut_body_list, entity_list); 03567 refedge_list.reset(); 03568 for (i = refedge_list.size(); i--; ) 03569 entity_list.append(refedge_list.get_and_step()); 03570 GeometryModifyEngine* gme = common_modify_engine( entity_list, bridge_list ); 03571 03572 if ( !gme ) 03573 { 03574 PRINT_ERROR("Performing WEBCUTS on volumes containing geometry from\n" 03575 "different modeling engines is not allowed.\n" 03576 "Delete uncommon geometry on these volumes before operation.\n\n"); 03577 return CUBIT_FAILURE; 03578 } 03579 03580 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 03581 { 03582 DLIList<Body*> bodies_to_save; 03583 bodies_to_save += webcut_body_list; 03584 bodies_to_save += neighboring_bodies; 03585 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 03586 } 03587 03588 DLIList<BodySM*> body_sm_list(webcut_body_list.size()), result_sm_list; 03589 DLIList<Curve*> curve_list(refedge_list.size()); 03590 CAST_LIST(bridge_list, body_sm_list, BodySM); 03591 CAST_LIST(bridge_list, curve_list, Curve); 03592 assert(body_sm_list.size() == webcut_body_list.size()); 03593 assert(curve_list.size() == refedge_list.size()); 03594 03595 DLIList<int> merged_surface_ids; 03596 DLIList<int> merged_curve_ids; 03597 DLIList<BodySM*> neighbor_imprint_list; 03598 DLIList<Body*> bodies_to_modify; 03599 03600 //make copies of the curves. 03601 DLIList<Curve*> copied_curves; 03602 Curve* temp_curve = NULL; 03603 for (int i = curve_list.size(); i--;) 03604 { 03605 temp_curve = gme->make_Curve(curve_list.get_and_step()); 03606 if(temp_curve != NULL) 03607 copied_curves.append(temp_curve); 03608 } 03609 03610 //make a face out of the curves 03611 Surface * surf = gme->make_Surface(PLANE_SURFACE_TYPE, copied_curves, NULL, false ); 03612 if (surf == NULL) 03613 { 03614 PRINT_ERROR("webcut tool surface is not created from occ.\n"); 03615 return CUBIT_FAILURE; 03616 } 03617 03618 03619 //get cutting tool BodySM. 03620 BodySM* cutting_tool_ptr = gme->make_BodySM(surf); 03621 assert(cutting_tool_ptr ); 03622 03623 if (!preview) 03624 { 03625 int i; 03626 for( i=neighboring_bodies.size(); i--; ) 03627 { 03628 Body *neighbor_body = neighboring_bodies.get_and_step(); 03629 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 03630 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 03631 03632 if( gme == neighbor_gme ) 03633 neighbor_imprint_list.append( tmp_body ); 03634 } 03635 03636 do_attribute_setup(); 03637 DLIList<BodySM*> bodies_sm_to_modify; 03638 bodies_sm_to_modify += body_sm_list; 03639 bodies_sm_to_modify += neighbor_imprint_list; 03640 push_attributes_before_modify( bodies_sm_to_modify ); 03641 bodies_to_modify += webcut_body_list; 03642 bodies_to_modify += neighboring_bodies; 03643 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 03644 } 03645 03646 03647 CubitStatus result_val = gme->webcut( 03648 body_sm_list, cutting_tool_ptr, 03649 neighbor_imprint_list, 03650 result_sm_list, 03651 imprint_type, preview) ; 03652 03653 // Delete the BodySM that was created to be used as a tool 03654 gme->get_gqe()->delete_solid_model_entities(cutting_tool_ptr) ; 03655 03656 // finish up if we're doing the real thing 03657 if (!preview) 03658 { 03659 restore_vg_after_modify(result_sm_list, bodies_to_modify, gme); 03660 remove_pushed_attributes(result_sm_list, bodies_to_modify); 03661 03662 result_val = finish_webcut( webcut_body_list, result_sm_list, merge, 03663 result_val, results_list, 03664 &merged_surface_ids, &merged_curve_ids ); 03665 do_attribute_cleanup(); 03666 } 03667 03668 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 03669 { 03670 if( result_val == CUBIT_SUCCESS ) 03671 CubitUndo::note_result_bodies( results_list ); 03672 else 03673 CubitUndo::remove_last_undo(); 03674 } 03675 03676 return result_val; 03677 } 03678 03679 //------------------------------------------------------------------------- 03680 // Purpose : This functions webcuts a list of bodies through a plane 03681 // defined by a refFace. The newly created bodies are 03682 // merged and imprinted depeding on the respective flags. 03683 // 03684 // Special Notes : 03685 // 03686 // Creator : Raikanta Sahu 03687 // 03688 // Creation Date : 12/16/96 03689 //------------------------------------------------------------------------- 03690 03691 CubitStatus GeometryModifyTool::webcut_with_surface( 03692 DLIList<Body*>& webcut_body_list, 03693 RefFace* refFace, 03694 DLIList<Body*>& results_list, 03695 DLIList<Body*> &neighboring_bodies, 03696 ImprintType imprint_type, 03697 CubitBoolean merge, 03698 CubitBoolean preview) 03699 { 03700 //make sure that this refface is planar, or you'll get unexpected results 03701 if( refFace->geometry_type() != PLANE_SURFACE_TYPE ) 03702 { 03703 PRINT_ERROR("Surface %d is not planar.\n", refFace->id() ); 03704 return CUBIT_FAILURE; 03705 } 03706 03707 // Using the face, get three positions (CubitVectors :) :) ) 03708 // The positions can be used by a GeometryModifyEngine to generate its 03709 // own webcutting tool and perform the webcut. 03710 CubitVector vector1 = refFace->position_from_u_v(0, 1) ; 03711 CubitVector vector3 = refFace->position_from_u_v(1, 0) ; 03712 CubitVector vector2 = refFace->position_from_u_v(0, 0) ; 03713 03714 CubitStatus result_val = this->webcut_with_plane(webcut_body_list, vector1, 03715 vector2, vector3, results_list, neighboring_bodies, 03716 imprint_type, merge, preview) ; 03717 03718 return result_val; 03719 } 03720 03721 //------------------------------------------------------------------------- 03722 // Purpose : This functions webcuts a list of bodies using a plane 03723 // defined by a refFace. The newly created bodies are 03724 // merged and imprinted depending on the respective flags. 03725 // 03726 // Special Notes : 03727 // 03728 // Creator : Raikanta Sahu 03729 // 03730 // Creation Date : 12/16/96 03731 //------------------------------------------------------------------------- 03732 03733 CubitStatus GeometryModifyTool::webcut_with_body( 03734 DLIList<Body*>& webcut_body_list, 03735 Body* tool_body, 03736 DLIList<Body*>& results_list, 03737 DLIList<Body*> &neighboring_bodies, 03738 ImprintType imprint_type, 03739 CubitBoolean merge, 03740 CubitBoolean preview) 03741 { 03742 03743 CubitStatus ret; 03744 03745 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 03746 return CUBIT_FAILURE; 03747 03748 CubitBox tool_bounding_box = tool_body->bounding_box(); 03749 remove_bodies_outside_bounding_box( webcut_body_list, tool_bounding_box ); 03750 03751 if( webcut_body_list.size() == 0 ) 03752 { 03753 PRINT_INFO("Tool does not intersect any bodies/volumes.\n"); 03754 return CUBIT_FAILURE; 03755 } 03756 03757 DLIList<BodySM*> body_sm_list(webcut_body_list.size()), result_sm_list; 03758 BodySM* tool_sm = tool_body->get_body_sm_ptr(); 03759 GeometryModifyEngine* gme = 0; 03760 if (!tool_sm || !(gme = get_engine(tool_sm))) 03761 { 03762 PRINT_DEBUG_153("No modify engine available for body %d.\n", tool_body->id()); 03763 PRINT_ERROR("No modify engine available for volume %d.\n", tool_body->ref_volume()->id()); 03764 return CUBIT_FAILURE; 03765 } 03766 03767 webcut_body_list.reset(); 03768 int i; 03769 for (i = webcut_body_list.size(); i--; ) 03770 { 03771 Body* body_ptr = webcut_body_list.get_and_step(); 03772 BodySM* sm_ptr = body_ptr->get_body_sm_ptr(); 03773 if (!sm_ptr || get_engine(sm_ptr) != gme) 03774 { 03775 PRINT_DEBUG_153("ERROR: Body %d does not belong to the same geometric engine " 03776 "as body %d\n", body_ptr->id(), tool_body->id()); 03777 PRINT_ERROR("Volume %d does not belong to the same geometric engine " 03778 "as volume %d\n", body_ptr->ref_volume()->id(), tool_body->ref_volume()->id()); 03779 return CUBIT_FAILURE; 03780 } 03781 03782 body_sm_list.append(sm_ptr); 03783 } 03784 03785 DLIList<int> merged_surface_ids; 03786 DLIList<int> merged_curve_ids; 03787 DLIList<BodySM*> neighbor_imprint_list; 03788 DLIList<Body*> bodies_to_modify; 03789 03790 if (!preview) 03791 { 03792 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 03793 { 03794 DLIList<Body*> bodies_to_save; 03795 bodies_to_save += webcut_body_list; 03796 bodies_to_save += neighboring_bodies; 03797 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 03798 } 03799 03800 int i; 03801 for( i=neighboring_bodies.size(); i--; ) 03802 { 03803 Body *neighbor_body = neighboring_bodies.get_and_step(); 03804 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 03805 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 03806 03807 if( gme == neighbor_gme ) 03808 neighbor_imprint_list.append( tmp_body ); 03809 } 03810 03811 do_attribute_setup(); 03812 DLIList<BodySM*> bodies_sm_to_modify; 03813 bodies_sm_to_modify += body_sm_list; 03814 bodies_sm_to_modify += neighbor_imprint_list; 03815 push_attributes_before_modify( bodies_sm_to_modify ); 03816 bodies_to_modify += webcut_body_list; 03817 bodies_to_modify += neighboring_bodies; 03818 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 03819 } 03820 03821 03822 int count = gme->webcut(body_sm_list, tool_sm, 03823 neighbor_imprint_list, 03824 result_sm_list, imprint_type, preview); 03825 03826 // finish up if we're doing the real thing 03827 if (!preview) 03828 { 03829 restore_vg_after_modify(result_sm_list, bodies_to_modify, gme); 03830 remove_pushed_attributes(result_sm_list, bodies_to_modify ); 03831 03832 ret = finish_webcut(webcut_body_list, result_sm_list, merge, 03833 count > 0 ? CUBIT_SUCCESS : CUBIT_FAILURE, 03834 results_list, &merged_surface_ids, &merged_curve_ids ); 03835 03836 do_attribute_cleanup(); 03837 } 03838 else 03839 ret = count > 0 ? CUBIT_SUCCESS : CUBIT_FAILURE; 03840 03841 if( preview == CUBIT_FALSE && CubitUndo::get_undo_enabled() ) 03842 { 03843 if( ret == CUBIT_SUCCESS ) 03844 CubitUndo::note_result_bodies( results_list ); 03845 else 03846 CubitUndo::remove_last_undo(); 03847 } 03848 03849 return ret; 03850 } 03851 03852 CubitStatus GeometryModifyTool::section( 03853 DLIList<Body*> §ion_body_list, 03854 const CubitVector &point_1, 03855 const CubitVector &point_2, 03856 const CubitVector &point_3, 03857 DLIList<Body*> &new_body_list, 03858 CubitBoolean keep_normal_side, 03859 CubitBoolean keep_old ) 03860 { 03861 if( section_body_list.size() == 0 ) 03862 return CUBIT_FAILURE; 03863 03864 if (!okay_to_modify( section_body_list, "SECTION" )) 03865 return CUBIT_FAILURE; 03866 CubitStatus rval = CUBIT_SUCCESS; 03867 03868 const int count = section_body_list.size(); 03869 DLIList<BodySM*> result_sm_list; 03870 DLIList<Body*> body_list(section_body_list); 03871 DLIList<BodySM*> engine_body_sms(count); 03872 DLIList<Body*> engine_bodies(count); 03873 GeometryModifyEngine* gme = 0; 03874 03875 if( CubitUndo::get_undo_enabled() ) 03876 { 03877 if( keep_old ) 03878 CubitUndo::save_state(); 03879 else 03880 CubitUndo::save_state_with_cubit_file( section_body_list ); 03881 } 03882 03883 while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) ) 03884 { 03885 //get all the child entities that have been merged 03886 DLIList<int> merged_surface_ids; 03887 DLIList<int> merged_curve_ids; 03888 get_merged_curve_and_surface_ids( engine_bodies, merged_surface_ids, merged_curve_ids ); 03889 03890 CubitStatus result = gme->section( engine_body_sms, 03891 point_1, point_2, point_3, 03892 result_sm_list, 03893 keep_normal_side, keep_old ); 03894 03895 if (!finish_sm_op( engine_bodies, result_sm_list, new_body_list )) 03896 result = CUBIT_FAILURE; 03897 if (!result) 03898 rval = CUBIT_FAILURE; 03899 03900 if( merged_surface_ids.size() || merged_curve_ids.size() ) 03901 fixup_merged_entities( merged_surface_ids, merged_curve_ids); 03902 03903 engine_body_sms.clean_out(); 03904 engine_bodies.clean_out(); 03905 result_sm_list.clean_out(); 03906 } 03907 03908 if( CubitUndo::get_undo_enabled() ) 03909 { 03910 if( new_body_list.size() ) //if there are new bodies...something succeeded 03911 CubitUndo::note_result_bodies( new_body_list ); 03912 else 03913 CubitUndo::remove_last_undo(); 03914 } 03915 03916 return rval; 03917 } 03918 03919 CubitStatus 03920 GeometryModifyTool::offset_curves( DLIList<RefEdge*>& ref_edge_list, 03921 DLIList<RefEdge*>& output_edge_list, 03922 double offset_distance, 03923 const CubitVector& offset_direction, 03924 int gap_type ) 03925 { 03926 // Make sure all curves are from same geometry engine 03927 DLIList<TopologyEntity*> entity_list(ref_edge_list.size()); 03928 DLIList<TopologyBridge*> bridge_list(ref_edge_list.size()); 03929 CAST_LIST_TO_PARENT(ref_edge_list, entity_list); 03930 GeometryModifyEngine* gme_ptr = common_modify_engine(entity_list, bridge_list); 03931 if ( !gme_ptr ) 03932 { 03933 PRINT_ERROR("Can't create offset curves that don't all originate from same\n" 03934 " modeling engine.\n"); 03935 return CUBIT_FAILURE; 03936 } 03937 03938 if( CubitUndo::get_undo_enabled() ) 03939 CubitUndo::save_state(); 03940 03941 DLIList<Curve*> curve_list(bridge_list.size()), result_list; 03942 CAST_LIST(bridge_list, curve_list, Curve); 03943 assert(curve_list.size() == ref_edge_list.size()); 03944 03945 CubitStatus rval = gme_ptr->offset_curves( curve_list, result_list, 03946 offset_distance, offset_direction, gap_type ); 03947 assert( rval || !result_list.size() ); 03948 result_list.reset(); 03949 03950 DLIList<RefEntity*> created_edges; 03951 output_edge_list.clean_out(); 03952 for (int i = result_list.size(); i--; ) 03953 { 03954 RefEdge *new_edge = GeometryQueryTool::instance()->make_free_RefEdge(result_list.get_and_step()); 03955 created_edges.append( new_edge ); 03956 output_edge_list.append( new_edge ); 03957 } 03958 03959 if( CubitUndo::get_undo_enabled() ) 03960 { 03961 if( created_edges.size() ) 03962 CubitUndo::note_result_entities( created_edges ); 03963 else 03964 CubitUndo::remove_last_undo(); 03965 } 03966 03967 return rval; 03968 } 03969 03970 // Compute the transformation requried to align my_face with target_face 03971 // with respecct to reference_body_ptr. Then perform the transformation 03972 // on all entities in entities_to_move 03973 CubitStatus GeometryModifyTool::align_entities( RefFace *source_face, 03974 RefFace *target_face, 03975 DLIList<RefEntity*> &entities_to_move, 03976 bool reverse, 03977 CubitVector &my_center, 03978 CubitVector &axis_of_rot, 03979 CubitVector &target_center, 03980 double &angle, 03981 bool preview) 03982 { 03983 // Initialize angle to zero, so we are passing back a valid 03984 // value if we never need to rotate the body 03985 angle = 0.0; 03986 03987 //Align the body, which contains my_face, with the target_face. 03988 03989 //Essentially we want to align the body at my_face with the target_face. 03990 my_center = source_face->center_point(); 03991 target_center = target_face->center_point(); 03992 03993 CubitVector my_vector = source_face->normal_at( my_center ); 03994 CubitVector target_vector = target_face->normal_at( target_center ); 03995 03996 if( CubitUndo::get_undo_enabled() && !preview ) 03997 { 03998 DLIList<RefEntity*> free_ents_to_save; 03999 DLIList<Body*> align_list(entities_to_move.size()); 04000 for ( int k=0; k<entities_to_move.size(); k++ ) 04001 { 04002 RefEntity *ref_ent = entities_to_move[k]; 04003 Body *tmp_body = dynamic_cast<Body*>(ref_ent); 04004 if( tmp_body ) 04005 align_list.append( tmp_body ); 04006 else 04007 free_ents_to_save.append( ref_ent ); 04008 } 04009 CubitUndo::save_state_with_cubit_file( align_list, &free_ents_to_save ); 04010 } 04011 04012 axis_of_rot = my_vector * target_vector; 04013 04014 if( axis_of_rot.length() < CUBIT_RESABS ) 04015 { 04016 CubitVector v1,v2; 04017 my_vector.orthogonal_vectors(v1, v2 ); 04018 axis_of_rot = v1; 04019 } 04020 04021 if( axis_of_rot.length() > CUBIT_RESABS ) 04022 { 04023 angle = axis_of_rot.vector_angle( my_vector, target_vector ); 04024 04025 //Now we have the angle and the axis to rotate about... 04026 angle = 180.0*angle/CUBIT_PI; 04027 04028 if( angle > 90 ) 04029 angle = angle - 180; 04030 04031 if( reverse ) 04032 angle += 180; 04033 } 04034 CubitVector origin(0.,0.,0.); 04035 04036 if (preview) 04037 { 04038 preview_align( -my_center, target_center, angle, axis_of_rot, entities_to_move ); 04039 } 04040 else 04041 { 04042 //Move the body so that the center of my_face 04043 //is at the origin. 04044 DLIList<RefEntity*> entities_transformed; 04045 GeometryQueryTool::instance()->translate( entities_to_move, 04046 -my_center.x(), 04047 -my_center.y(), 04048 -my_center.z(), 04049 false, 04050 entities_transformed); 04051 04052 //If the axis length is zero we dont want to do a rotation, 04053 //they are already parallel.. 04054 if (axis_of_rot.length() > CUBIT_RESABS ) 04055 { 04056 //Now rotate the body about the axis. 04057 GeometryQueryTool::instance()->rotate(entities_to_move, origin, 04058 axis_of_rot, angle, false, entities_transformed, 04059 false); 04060 } 04061 //Now move the body to the location of the target_center. 04062 GeometryQueryTool::instance()->translate( entities_to_move, 04063 target_center.x(), 04064 target_center.y(), 04065 target_center.z(), 04066 false, 04067 entities_transformed, 04068 preview); 04069 } 04070 04071 //That should do it. 04072 return CUBIT_SUCCESS; 04073 } 04074 04075 CubitStatus GeometryModifyTool::align_entities( DLIList<RefEntity*> &entities_to_align, 04076 CubitVector &pos_to_align, 04077 CubitVector &pos_to_align_to, 04078 CubitVector &axis_origin, 04079 CubitVector &axis_of_rot, 04080 double &angle_of_rotation, 04081 bool preview) 04082 { 04083 //project pos_to_align to axis 04084 axis_of_rot.normalize(); 04085 CubitVector tmp_vec = pos_to_align - axis_origin; 04086 double dot_prod = tmp_vec%axis_of_rot; 04087 CubitVector int_pt1 = axis_origin + (dot_prod*axis_of_rot); 04088 04089 //project pos_to_align_to to axis 04090 tmp_vec = pos_to_align_to - axis_origin; 04091 dot_prod = tmp_vec%axis_of_rot; 04092 CubitVector int_pt2 = axis_origin + (dot_prod*axis_of_rot); 04093 04094 //determine angle of rotation 04095 tmp_vec = pos_to_align - int_pt1; 04096 CubitVector tmp_vec2 = pos_to_align_to - int_pt2; 04097 angle_of_rotation = axis_of_rot.vector_angle( tmp_vec, tmp_vec2 ); 04098 angle_of_rotation *= 180.0/CUBIT_PI; 04099 04100 if( angle_of_rotation < CUBIT_RESABS ) 04101 { 04102 PRINT_WARNING("Points already aligned.\n"); 04103 return CUBIT_SUCCESS; 04104 } 04105 04106 if( CubitUndo::get_undo_enabled() && !preview ) 04107 { 04108 DLIList<RefEntity*> free_ents_to_save; 04109 DLIList<Body*> align_list(entities_to_align.size()); 04110 for ( int k=0; k<entities_to_align.size(); k++ ) 04111 { 04112 RefEntity *ref_ent = entities_to_align[k]; 04113 Body *tmp_body = dynamic_cast<Body*>(ref_ent); 04114 if( tmp_body ) 04115 align_list.append( tmp_body ); 04116 else 04117 free_ents_to_save.append( ref_ent ); 04118 } 04119 CubitUndo::save_state_with_cubit_file( align_list, &free_ents_to_save ); 04120 } 04121 04122 CubitVector translation_vector( int_pt1 ); 04123 04124 if( preview ) 04125 { 04126 preview_align( -translation_vector, translation_vector, 04127 angle_of_rotation, axis_of_rot, entities_to_align ); 04128 } 04129 else 04130 { 04131 //translate to origin 04132 DLIList<RefEntity*> entities_transformed; 04133 GeometryQueryTool::instance()->translate( entities_to_align, 04134 -translation_vector.x(), 04135 -translation_vector.y(), 04136 -translation_vector.z(), 04137 false, 04138 entities_transformed); 04139 04140 //rotate to align 04141 CubitVector origin(0,0,0); 04142 GeometryQueryTool::instance()->rotate( entities_to_align, origin, axis_of_rot, angle_of_rotation, false, 04143 entities_transformed, false ); 04144 04145 //translate back 04146 GeometryQueryTool::instance()->translate( entities_to_align, 04147 translation_vector.x(), 04148 translation_vector.y(), 04149 translation_vector.z(), 04150 false, 04151 entities_transformed); 04152 } 04153 04154 //That should do it. 04155 return CUBIT_SUCCESS; 04156 } 04157 04158 CubitStatus GeometryModifyTool::align_entities( DLIList<RefEntity*>& reference_entities, 04159 DLIList<RefEntity*> &entities_to_move, 04160 CubitVector align_to_vec, 04161 CubitVector &my_center, 04162 CubitVector &axis_of_rot, 04163 double &angle, 04164 bool preview) 04165 { 04166 DLIList<RefFace*> ref_face_list; 04167 DLIList<RefVertex*> ref_vertex_list; 04168 04169 CAST_LIST(reference_entities, ref_face_list, RefFace); 04170 CAST_LIST(reference_entities, ref_vertex_list, RefVertex); 04171 04172 angle = 0.0; 04173 04174 CubitVector translation_vector; 04175 CubitVector axis_of_rotation; 04176 CubitVector vector_to_rotate; 04177 04178 if( ref_face_list.size() == 1 && 04179 ref_vertex_list.size() == 0 ) 04180 { 04181 //now form the axis of rotation 04182 RefFace *my_face = ref_face_list.get_and_step(); 04183 translation_vector = my_face->center_point(); 04184 my_center = translation_vector; 04185 vector_to_rotate = my_face->normal_at( translation_vector ); 04186 axis_of_rot = align_to_vec * vector_to_rotate; 04187 } 04188 else if( ref_face_list.size() == 0 && 04189 ref_vertex_list.size() == 2 ) 04190 { 04191 RefVertex *vertex_1 = ref_vertex_list.get_and_step(); 04192 RefVertex *vertex_2 = ref_vertex_list.get_and_step(); 04193 04194 //now form the axis of rotation 04195 translation_vector = vertex_1->coordinates(); 04196 my_center = vertex_1->coordinates(); 04197 vector_to_rotate = vertex_2->coordinates() - vertex_1->coordinates(); 04198 axis_of_rot = align_to_vec * vector_to_rotate; 04199 } 04200 04201 if( axis_of_rot.length() < CUBIT_RESABS ) 04202 { 04203 double dot_prod = align_to_vec%vector_to_rotate; 04204 //normals could be 180 degrees from one another 04205 if( dot_prod < 0 ) 04206 { 04207 CubitVector v1,v2; 04208 align_to_vec.orthogonal_vectors(v1, v2 ); 04209 axis_of_rot = v1; 04210 } 04211 } 04212 04213 if( CubitUndo::get_undo_enabled() && !preview ) 04214 { 04215 DLIList<RefEntity*> free_ents_to_save; 04216 DLIList<Body*> align_list(entities_to_move.size()); 04217 for ( int k=0; k<entities_to_move.size(); k++ ) 04218 { 04219 RefEntity *ref_ent = entities_to_move[k]; 04220 Body *tmp_body = dynamic_cast<Body*>(ref_ent); 04221 if( tmp_body ) 04222 align_list.append( tmp_body ); 04223 else 04224 free_ents_to_save.append( ref_ent ); 04225 } 04226 CubitUndo::save_state_with_cubit_file( align_list, &free_ents_to_save ); 04227 } 04228 04229 //determine the angle of rotation 04230 angle = axis_of_rot.vector_angle( vector_to_rotate, align_to_vec ); 04231 angle = 180.0*angle/CUBIT_PI; 04232 04233 if( preview ) 04234 { 04235 preview_align( -translation_vector, translation_vector, 04236 angle, axis_of_rot, entities_to_move ); 04237 } 04238 else 04239 { 04240 //translate to origin 04241 DLIList<RefEntity*> entities_transformed; 04242 GeometryQueryTool::instance()->translate( entities_to_move, 04243 -translation_vector.x(), 04244 -translation_vector.y(), 04245 -translation_vector.z(), 04246 false, 04247 entities_transformed); 04248 04249 //rotate to align 04250 CubitVector origin(0,0,0); 04251 GeometryQueryTool::instance()->rotate( entities_to_move, origin, axis_of_rot, angle, false, 04252 entities_transformed, false ); 04253 04254 //translate back 04255 GeometryQueryTool::instance()->translate( entities_to_move, 04256 translation_vector.x(), 04257 translation_vector.y(), 04258 translation_vector.z(), 04259 false, 04260 entities_transformed); 04261 } 04262 04263 //That should do it. 04264 return CUBIT_SUCCESS; 04265 } 04266 04267 void GeometryModifyTool::preview_align( CubitVector translation_to_origin, 04268 CubitVector origin_to_target, 04269 double angle_of_rotation, 04270 CubitVector axis_of_rotation, 04271 DLIList<RefEntity*> &entities ) 04272 { 04273 CubitTransformMatrix prev_xform; 04274 prev_xform.translate(translation_to_origin); 04275 04276 CubitTransformMatrix rot_mat; 04277 rot_mat.rotate( angle_of_rotation, axis_of_rotation ); 04278 04279 CubitTransformMatrix mov_mat; 04280 mov_mat.translate( origin_to_target ); 04281 04282 for( int k=0; k<entities.size(); k++ ) 04283 { 04284 RefEntity *tmp_ent = entities[k]; 04285 TopologyEntity *te = dynamic_cast<TopologyEntity*>(tmp_ent); 04286 if( NULL == te ) 04287 continue; 04288 04289 DLIList<RefEdge*> edges; 04290 te->ref_edges(edges); 04291 for (int i = 0; i < edges.size(); i++) 04292 { 04293 GMem poly; 04294 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 04295 { 04296 poly.transform(prev_xform); 04297 poly.transform(rot_mat); 04298 poly.transform(mov_mat); 04299 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 04300 } 04301 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 04302 { 04303 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 04304 tmp_pt = prev_xform*tmp_pt; 04305 tmp_pt = rot_mat*tmp_pt; 04306 tmp_pt = mov_mat*tmp_pt; 04307 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 04308 } 04309 } 04310 } 04311 } 04312 04313 04314 04315 CubitStatus GeometryModifyTool::sweep_setup( 04316 const char* name, 04317 DLIList<RefEntity*>& input_entity_list, 04318 DLIList<Body*>& output_body_list, 04319 GeometryModifyEngine*& output_engine, 04320 CubitBoolean& changed_new_ids, 04321 DLIList<GeometryEntity*>& output_geom_list, 04322 bool keep_old, 04323 DLIList<RefEdge*>* input_edge_list, 04324 DLIList<Curve*>* output_curve_list ) 04325 { 04326 int i; 04327 04328 if (input_entity_list.size() == 0) 04329 return CUBIT_FAILURE; 04330 04331 DLIList<RefFace*> ref_face_list; 04332 DLIList<RefEdge*> ref_edge_list; 04333 CAST_LIST( input_entity_list, ref_face_list, RefFace ); 04334 CAST_LIST( input_entity_list, ref_edge_list, RefEdge ); 04335 if( ref_face_list.size() && ref_edge_list.size() ) 04336 { 04337 PRINT_ERROR( "Currently cannot sweep curves and surfaces at the same time\n" ); 04338 return CUBIT_FAILURE; 04339 } 04340 04341 if( (ref_face_list.size()+ref_edge_list.size()) != input_entity_list.size() ) 04342 { 04343 PRINT_ERROR( "Can only sweep surfaces or curves\n" ); 04344 return CUBIT_FAILURE; 04345 } 04346 04347 // Currently faces to be swept have to belong to different bodies. It 04348 // doesn't work well to sweep multiple faces from the same body (also 04349 // current implementation in AGE crashes). 04350 if( ref_face_list.size() && false == keep_old ) 04351 { 04352 int free_surf_cnt = 0; // Number of free surfaces being swept 04353 DLIList<Body*> body_list; 04354 RefFace *ref_face_ptr; 04355 for( i=ref_face_list.size(); i--; ) 04356 { 04357 ref_face_ptr = ref_face_list.get_and_step(); 04358 DLIList<Body*> tmp_body_list; 04359 ref_face_ptr->bodies( tmp_body_list ); 04360 if( tmp_body_list.size() > 1 ) 04361 { 04362 PRINT_ERROR( "Surface %d belongs to more than one volume; cannot sweep.\n", 04363 ref_face_ptr->id() ); 04364 return CUBIT_FAILURE; 04365 } 04366 04367 if( tmp_body_list.size() > 0 ) 04368 body_list.append_unique( tmp_body_list.get() ); 04369 else 04370 free_surf_cnt++; 04371 } 04372 04373 if( body_list.size()+free_surf_cnt != ref_face_list.size() ) 04374 { 04375 //if each is a sheet body, and every surface is in the list, 04376 //it is ok to sweep it 04377 04378 //PRINT_ERROR("The surfaces to be swept cannot belong to the same volume\n"); 04379 //return CUBIT_FAILURE; 04380 04381 for( int k=body_list.size(); k--; ) 04382 { 04383 Body *tmp_body = body_list.get_and_step(); 04384 DLIList<RefFace*> tmp_ref_faces; 04385 tmp_body->ref_faces( tmp_ref_faces ); 04386 04387 //all surfaces must be swept 04388 if( tmp_body->is_sheet_body() ) 04389 { 04390 tmp_ref_faces -= ref_face_list; 04391 if( tmp_ref_faces.size() ) 04392 { 04393 PRINT_ERROR( "When sweeping a sheet body, all surfaces must be specified\n"); 04394 return CUBIT_FAILURE; 04395 } 04396 } 04397 else // only 1 surface can be swept 04398 { 04399 int num_surfaces_before = tmp_ref_faces.size(); 04400 tmp_ref_faces -= ref_face_list; 04401 04402 if( (num_surfaces_before - tmp_ref_faces.size() ) > 1 ) 04403 { 04404 PRINT_ERROR( "The surfaces to be swept cannot belong to the same volume\n" ); 04405 return CUBIT_FAILURE; 04406 } 04407 } 04408 } 04409 } 04410 04411 output_body_list = body_list; 04412 } 04413 04414 // Make sure all entities are from same modify engine 04415 DLIList<TopologyEntity*> te_list; 04416 CAST_LIST(input_entity_list, te_list, TopologyEntity); 04417 04418 // This is for sweeping along a curve list 04419 if (input_edge_list) 04420 { 04421 input_edge_list->reset(); 04422 for( i=input_edge_list->size(); i--; ) 04423 te_list.append( input_edge_list->get_and_step() ); 04424 } 04425 04426 DLIList<TopologyBridge*> bridge_list( te_list.size() ); 04427 output_engine = common_modify_engine( te_list, bridge_list ); 04428 if( output_engine == NULL ) 04429 { 04430 PRINT_ERROR("Can't sweep with entities from different modeling engines.\n"); 04431 return CUBIT_FAILURE; 04432 } 04433 04434 // Check for virtual anywhere in participating bodies. This will catch cases where 04435 // the result from sweeping would interact with some virtual somewhere. bwc 12/22/05. 04436 for(i=output_body_list.size(); i--;) 04437 { 04438 if(GeometryQueryTool::instance()->contains_intermediate_geometry( 04439 output_body_list.get_and_step())) 04440 { 04441 PRINT_ERROR("Can't sweep faces of bodies containing virtual geometry.\n"); 04442 return CUBIT_FAILURE; 04443 } 04444 } 04445 04446 changed_new_ids = CUBIT_FALSE; 04447 04448 TopologyBridge* bridge_ptr; 04449 bridge_list.reset(); 04450 for( i=input_entity_list.size(); i--; ) 04451 { 04452 bridge_ptr = bridge_list.get_and_step(); 04453 GeometryEntity* geom_ptr = dynamic_cast<GeometryEntity*>(bridge_ptr); 04454 output_geom_list.append(geom_ptr); 04455 } 04456 04457 if( input_edge_list ) 04458 { 04459 for( i=input_edge_list->size(); i--; ) 04460 { 04461 bridge_ptr = bridge_list.get_and_step(); 04462 Curve* curve_ptr = dynamic_cast<Curve*>(bridge_ptr); 04463 output_curve_list->append(curve_ptr); 04464 } 04465 } 04466 04467 return CUBIT_SUCCESS; 04468 } 04469 04470 CubitStatus GeometryModifyTool::sweep_finish( 04471 const char* const, 04472 DLIList<Body*>& input_body_list, 04473 DLIList<BodySM*>& new_body_list, 04474 DLIList<Body*>& output_body_list, 04475 CubitBoolean changed_new_ids ) 04476 { 04477 int i; 04478 DLIList<BodySM*> regen_list( new_body_list ); 04479 GeometryQueryTool *gqt = GeometryQueryTool::instance(); 04480 04481 input_body_list.reset(); 04482 for (i = input_body_list.size(); i--; ) 04483 { 04484 Body* body = input_body_list.get_and_step(); 04485 BodySM* bodysm = body->get_body_sm_ptr(); 04486 if (bodysm) 04487 { 04488 regen_list.append_unique(bodysm); 04489 remove_dead_entity_names(body); 04490 output_body_list.append( body ); 04491 } 04492 else 04493 { 04494 gqt->destroy_dead_entity(body); 04495 } 04496 } 04497 gqt->cleanout_deactivated_geometry(); 04498 04499 regen_list.reset(); 04500 for (i = regen_list.size(); i--; ) 04501 { 04502 BodySM* bodysm = regen_list.get_and_step(); 04503 Body* body = gqt->make_Body(bodysm); 04504 output_body_list.append_unique( body ); 04505 PRINT_INFO("%s volume %d\n", 04506 new_body_list.is_in_list(bodysm) ? "Created swept" : "Updated", 04507 body->ref_volume()->id()); 04508 } 04509 04510 if (changed_new_ids) set_new_ids(CUBIT_FALSE); 04511 gqt->cleanout_deactivated_geometry(); 04512 04513 return CUBIT_SUCCESS; 04514 } 04515 04516 04517 04518 04519 04520 CubitStatus GeometryModifyTool::sweep_rotational( 04521 DLIList<RefEntity*>& ref_ent_list, 04522 const CubitVector& point, 04523 const CubitVector& sweep_axis, 04524 double angle, 04525 DLIList<Body*>& output_body_list, 04526 CubitBoolean anchor_entity, 04527 CubitBoolean keep_old, 04528 int steps, 04529 double draft_angle, 04530 int draft_type, 04531 CubitBoolean switchside, 04532 CubitBoolean make_solid, 04533 CubitBoolean rigid) 04534 { 04535 DLIList<Body*> body_list; 04536 DLIList<GeometryEntity*> geom_list; 04537 GeometryModifyEngine* gePtr1 = 0; 04538 CubitBoolean change_newids; 04539 if (!sweep_setup("rotational", ref_ent_list, body_list, gePtr1, 04540 change_newids, geom_list, keep_old)) 04541 return CUBIT_FAILURE; 04542 04543 if( CubitUndo::get_undo_enabled()) 04544 { 04545 DLIList<RefEdge*> edge_list; 04546 DLIList<RefFace*> face_list; 04547 04548 CAST_LIST( ref_ent_list, edge_list, RefEdge ); 04549 CAST_LIST( ref_ent_list, face_list, RefFace ); 04550 04551 DLIList<RefEdge*> free_edges; 04552 for(int i=0;i<edge_list.size();i++) 04553 { 04554 RefEdge* edge= edge_list[i]; 04555 if(edge->num_parent_ref_entities()==0) 04556 { 04557 free_edges.append(edge); 04558 } 04559 } 04560 04561 if(free_edges.size()) 04562 CubitUndo::save_state_with_cubit_file( free_edges ); 04563 else if( edge_list.size() || keep_old ) 04564 CubitUndo::save_state(); 04565 else 04566 //Faces will get consumed so you have to save out original entities 04567 CubitUndo::save_state_with_cubit_file( face_list ); 04568 } 04569 04570 DLIList<BodySM*> result_list; 04571 CubitStatus status = gePtr1->sweep_rotational( geom_list, 04572 result_list, 04573 point, 04574 sweep_axis, 04575 angle, 04576 steps, 04577 draft_angle, 04578 draft_type, 04579 switchside, 04580 make_solid, 04581 rigid, 04582 anchor_entity, 04583 keep_old ); 04584 04585 if( keep_old ) 04586 body_list.clean_out(); 04587 04588 if (!sweep_finish("rotational", body_list, result_list, output_body_list, change_newids)) 04589 status = CUBIT_FAILURE; 04590 04591 if( CubitUndo::get_undo_enabled()) 04592 { 04593 if( status == CUBIT_FAILURE ) 04594 CubitUndo::remove_last_undo(); 04595 else 04596 CubitUndo::note_result_bodies( output_body_list ); 04597 } 04598 04599 return status; 04600 } 04601 04602 04603 CubitStatus GeometryModifyTool::sweep_helical( DLIList<RefEntity*>& ref_ent_list, 04604 CubitVector &location, 04605 CubitVector &direction, 04606 double &thread_distance, 04607 double &angle, 04608 bool right_handed, 04609 CubitBoolean anchor_entity, 04610 CubitBoolean keep_old, 04611 DLIList<Body*>& output_body_list) 04612 { 04613 DLIList<Body*> body_list; 04614 DLIList<GeometryEntity*> geom_list; 04615 GeometryModifyEngine* gePtr1 = 0; 04616 CubitBoolean change_newids; 04617 if (!sweep_setup("translational", ref_ent_list, body_list, gePtr1, 04618 change_newids, geom_list, keep_old)) 04619 return CUBIT_FAILURE; 04620 04621 if( CubitUndo::get_undo_enabled()) 04622 { 04623 DLIList<RefEdge*> edge_list; 04624 DLIList<RefFace*> face_list; 04625 04626 CAST_LIST( ref_ent_list, edge_list, RefEdge ); 04627 CAST_LIST( ref_ent_list, face_list, RefFace ); 04628 04629 //Edges aren't consumed, so there's nothing to save out 04630 if( edge_list.size() || keep_old ) 04631 CubitUndo::save_state(); 04632 else 04633 //Faces will get consumed so you have to save out original entities 04634 CubitUndo::save_state_with_cubit_file( face_list ); 04635 } 04636 04637 DLIList<BodySM*> result_list; 04638 CubitStatus status = gePtr1-> 04639 sweep_helical( geom_list, result_list, location, 04640 direction, thread_distance, angle, right_handed, anchor_entity, keep_old ); 04641 04642 if( keep_old ) 04643 body_list.clean_out(); 04644 04645 if (!sweep_finish("translational", body_list, result_list, output_body_list, change_newids)) 04646 status = CUBIT_FAILURE; 04647 04648 if( CubitUndo::get_undo_enabled()) 04649 { 04650 if( status == CUBIT_FAILURE ) 04651 CubitUndo::remove_last_undo(); 04652 else 04653 CubitUndo::note_result_bodies( output_body_list ); 04654 } 04655 04656 return status; 04657 04658 04659 04660 04661 04662 } 04663 04664 CubitStatus GeometryModifyTool::sweep_translational( 04665 DLIList<RefEntity*>& ref_ent_list, 04666 const CubitVector& sweep_vector, 04667 double draft_angle, 04668 int draft_type, 04669 CubitBoolean switchside, 04670 CubitBoolean rigid, 04671 CubitBoolean anchor_entity, 04672 CubitBoolean keep_old, 04673 DLIList<Body*>& output_body_list) 04674 { 04675 DLIList<Body*> body_list; 04676 DLIList<GeometryEntity*> geom_list; 04677 GeometryModifyEngine* gePtr1 = 0; 04678 CubitBoolean change_newids; 04679 if (!sweep_setup("translational", ref_ent_list, body_list, gePtr1, 04680 change_newids, geom_list, keep_old)) 04681 return CUBIT_FAILURE; 04682 04683 if( CubitUndo::get_undo_enabled()) 04684 { 04685 DLIList<RefEdge*> edge_list; 04686 DLIList<RefFace*> face_list; 04687 04688 CAST_LIST( ref_ent_list, edge_list, RefEdge ); 04689 CAST_LIST( ref_ent_list, face_list, RefFace ); 04690 04691 //find any free edges 04692 DLIList<RefEdge*> free_edges; 04693 for( int k=edge_list.size(); k--; ) 04694 { 04695 RefEdge *tmp_edge = edge_list.get_and_step(); 04696 if( tmp_edge->num_parent_ref_entities() == 0 ) 04697 free_edges.append( tmp_edge ); 04698 } 04699 04700 if( free_edges.size() ) 04701 //Free edges will get consumed..save them out 04702 CubitUndo::save_state_with_cubit_file( free_edges ); 04703 else if( edge_list.size() || keep_old ) 04704 CubitUndo::save_state(); 04705 else 04706 //Faces will get consumed so you have to save out original entities 04707 CubitUndo::save_state_with_cubit_file( face_list ); 04708 } 04709 04710 DLIList<BodySM*> result_list; 04711 CubitStatus status = gePtr1-> 04712 sweep_translational( geom_list, 04713 result_list, 04714 sweep_vector, 04715 draft_angle, 04716 draft_type, 04717 switchside, 04718 rigid, 04719 anchor_entity, 04720 keep_old); 04721 04722 if( keep_old ) 04723 body_list.clean_out(); 04724 04725 if (!sweep_finish("translational", body_list, result_list, output_body_list, change_newids)) 04726 status = CUBIT_FAILURE; 04727 04728 if( CubitUndo::get_undo_enabled()) 04729 { 04730 if( status == CUBIT_FAILURE ) 04731 CubitUndo::remove_last_undo(); 04732 else 04733 CubitUndo::note_result_bodies( output_body_list ); 04734 } 04735 04736 return status; 04737 } 04738 04739 //Author:: Jonathan Bugman 04740 //Sept 10, 2006 04741 CubitStatus GeometryModifyTool::sweep_curve_target(CubitPlane ref_plane, 04742 DLIList<RefEntity*>& ref_ent_list) 04743 { 04744 double distance1; 04745 double distance2; 04746 double distance3; 04747 double temp_counter=0; 04748 CubitVector begin_point; 04749 CubitVector target_begin_point; 04750 CubitVector get_mid_point; 04751 CubitVector target_mid_point; 04752 CubitVector end_point; 04753 CubitVector target_end_point; 04754 DLIList<RefEdge*> edge_list; 04755 CAST_LIST(ref_ent_list, edge_list, RefEdge); 04756 CubitVector result; 04757 double max_distance_for_edge=0; 04758 CubitVector max_result; 04759 //make sure that there are actually edges in list 04760 if(edge_list.size() > 0) 04761 { 04762 //this part of the code steps through all edges that could be 04763 //selected by user and finds the largest distance of all edges from three 04764 //points: midpoint, endpoint, and beginpoint 04765 for (int i=0;i<edge_list.size();i++) 04766 { 04767 //find the midpoint vector of the edge 04768 edge_list[i]->mid_point(get_mid_point); 04769 04770 //Project the midpoint onto the specified plane 04771 target_mid_point = ref_plane.project(get_mid_point); 04772 04773 //Calculate the distance between the mid_point, and target_point 04774 distance1 = target_mid_point.distance_between(get_mid_point); 04775 04776 //the next two blocks are just copies of the above three steps 04777 double fraction_along_curve = 1; 04778 edge_list[i]->position_from_fraction(fraction_along_curve, end_point); 04779 target_end_point = ref_plane.project(end_point); 04780 distance2 = target_end_point.distance_between(end_point); 04781 04782 fraction_along_curve = 0; 04783 edge_list[i]->position_from_fraction(fraction_along_curve, begin_point); 04784 target_begin_point = ref_plane.project(begin_point); 04785 distance3 = target_begin_point.distance_between(begin_point); 04786 04787 //see which of the three distances is greater for that edge 04788 //and compare its distance to the other edges that have already been calculated 04789 //saving the vector of the largest distance 04790 if (distance1>distance2 && distance1>distance3) 04791 { 04792 result = 2*(target_mid_point - get_mid_point); 04793 max_distance_for_edge=distance1; 04794 if (max_distance_for_edge>temp_counter) 04795 { 04796 temp_counter=max_distance_for_edge; 04797 max_result=result; 04798 } 04799 } 04800 else if (distance2>distance3) 04801 { 04802 result = 2*(target_end_point - end_point); 04803 max_distance_for_edge=distance2; 04804 if (max_distance_for_edge>temp_counter) 04805 { 04806 temp_counter=max_distance_for_edge; 04807 max_result=result; 04808 } 04809 } 04810 else 04811 { 04812 result = 2*(target_begin_point - begin_point); 04813 max_distance_for_edge=distance3; 04814 if (max_distance_for_edge>temp_counter) 04815 { 04816 temp_counter=max_distance_for_edge; 04817 max_result=result; 04818 } 04819 } 04820 } 04821 04822 //using the 'facet edges' defined by the drawing geometry take the leading 04823 //and trailing edge projection vectors of this small edge. With that, 04824 //calc the dot product and if negative, the vectors are opposite of each 04825 //other meaning the curve travels through the plane and the sweep function will fail 04826 for (int ii=0;ii<edge_list.size();ii++) 04827 { 04828 Curve *facet_curve; 04829 facet_curve=edge_list[ii]->get_curve_ptr(); 04830 CubitStatus response; 04831 GMem g_mem; 04832 04833 //get number of points and their locations 04834 //on the curve as defined by the drawing geometry algorithm 04835 response = facet_curve->get_geometry_query_engine()-> 04836 get_graphics( facet_curve, &g_mem ); 04837 int num_points = g_mem.pointListCount; 04838 04839 if (response==CUBIT_FAILURE || num_points == 0) 04840 { 04841 PRINT_WARNING("Facet Curve calling function failed\n" ); 04842 } 04843 04844 GPoint *point_data = g_mem.point_list(); 04845 04846 for (int jj=0; jj < (num_points-1); jj++) 04847 { 04848 //get first points vectors 04849 CubitVector point_1; 04850 point_1.x(point_data[jj].x); 04851 point_1.y(point_data[jj].y); 04852 point_1.z(point_data[jj].z); 04853 //get second points vectors 04854 CubitVector point_2; 04855 point_2.x(point_data[jj+1].x); 04856 point_2.y(point_data[jj+1].y); 04857 point_2.z(point_data[jj+1].z); 04858 //project the two points onto target plane 04859 CubitVector target_point_1; 04860 target_point_1 = ref_plane.project(point_1); 04861 CubitVector target_point_2; 04862 target_point_2 = ref_plane.project(point_2); 04863 //calc vector from point on curve to point on surface 04864 CubitVector vec_1 = point_1 - target_point_1; 04865 CubitVector vec_2 = point_2 - target_point_2; 04866 //make them unit vectors 04867 vec_1.normalize(); 04868 vec_2.normalize(); 04869 //calculate dot product 04870 double dot = vec_1.x()*vec_2.x()+vec_1.y()*vec_2.y()+vec_1.z()*vec_2.z(); 04871 //check to see if dot product sign is zero 04872 //the and statement checks for if the first or last vertex of the edge 04873 //which may be sitting on the surface, this is alright 04874 //and should still be able to sweep 04875 // if (dot<0 && (jj+1!=num_points || jj==0)) 04876 if (dot<0 && (jj!=(num_points-2) || jj==0)) 04877 { 04878 PRINT_ERROR( "The edge is traveling through the plane\n" ); 04879 PRINT_ERROR( "and thus forces the sweep direction to switch\n" ); 04880 PRINT_ERROR( "direction. Try splitting the edge.\n" ); 04881 return CUBIT_FAILURE; 04882 } 04883 } 04884 } 04885 DLIList<BodySM*> webcut_results_list; 04886 DLIList<Body*> body_list; 04887 DLIList<BodySM*> sweep_result_list; 04888 DLIList<GeometryEntity*> geom_list; 04889 GeometryModifyEngine* gePtr1 = 0; 04890 CubitBoolean change_newids; 04891 04892 if (!sweep_setup("translational", ref_ent_list , body_list, gePtr1, 04893 change_newids, geom_list, false)) 04894 return CUBIT_FAILURE; 04895 04896 //below block is default settings to be fed into sweep_translational 04897 CubitBoolean rigid = CUBIT_FALSE; 04898 CubitBoolean switchside = CUBIT_FALSE; 04899 int draft_type = 0; 04900 double draft_angle=0.0; 04901 04902 //sweep the curve through and hopefully past the target surface 04903 CubitStatus status = gePtr1->sweep_translational( geom_list,sweep_result_list, 04904 max_result,draft_angle, draft_type,switchside,rigid); 04905 04906 if (status == 0) 04907 { 04908 PRINT_ERROR( "Sweep operation failed!\n" ); 04909 //delete sweep_result_list memory 04910 gePtr1->get_gqe()->delete_solid_model_entities(sweep_result_list); 04911 return CUBIT_FAILURE; 04912 } 04913 04914 //below lines are used to define the ref_plane with three points for webcut input 04915 //find normal vector to user specified plane 04916 CubitVector vec1 = ref_plane.normal(); 04917 CubitVector vec2; 04918 CubitVector vec3; 04919 //get orthogonal vectors of the normal vector 04920 vec1.orthogonal_vectors(vec2, vec3); 04921 //place the orthogonal vectors at a point on the plane as opposed to the origin 04922 vec2=vec2+target_mid_point; 04923 vec3=vec3+target_mid_point; 04924 04925 DLIList<BodySM*> neighbor_imprint_list; 04926 //do a webcut with a plane created from the three projected points above 04927 CubitStatus status2 = gePtr1->webcut(sweep_result_list,target_mid_point, 04928 vec2,vec3, neighbor_imprint_list, webcut_results_list); 04929 04930 if (status2 == 0) 04931 { 04932 PRINT_ERROR( "Sweep operation worked; however, webcut operation failed.\n" ); 04933 //delete memory since it failed 04934 gePtr1->get_gqe()->delete_solid_model_entities(sweep_result_list); 04935 return CUBIT_FAILURE; 04936 } 04937 04938 if (webcut_results_list.size()==0) 04939 { 04940 PRINT_ERROR( "Number of bodies from webcut is zero, unable to perform rest of sweep operation\n" ); 04941 //delete memory since it failed 04942 gePtr1->get_gqe()->delete_solid_model_entities(sweep_result_list); 04943 return CUBIT_FAILURE; 04944 } 04945 04946 CubitVector created_curve_mid; 04947 CubitVector user_mid; 04948 DLIList<BodySM*> keep_bodies_list; 04949 DLIList<Curve*> curve_list; 04950 04951 //generate a list of curves from the webcut_results_list 04952 for (int counter = 0;counter < webcut_results_list.size(); counter++) 04953 { 04954 BodySM* OO = webcut_results_list[counter]; 04955 OO->curves(curve_list); 04956 } 04957 04958 //step through each of the user specified edges 04959 for (int edge_counter = 0; edge_counter < edge_list.size(); edge_counter++) 04960 { 04961 //find the midpoint of a user specified edge 04962 edge_list[edge_counter]->position_from_fraction(.5,user_mid); 04963 double min_dist=DBL_MAX; 04964 double distance; 04965 Curve* closest_curve=0; 04966 04967 //step through all of the curves 04968 for (int counter2 = 0; counter2 < curve_list.size(); counter2++) 04969 { 04970 //find the midpoint of the created curve 04971 curve_list[counter2]->position_from_fraction(.5,created_curve_mid); 04972 //calculate the distance between the two midpoints 04973 distance=created_curve_mid.distance_between(user_mid); 04974 04975 //find the minimum distance between all the curves 04976 if (distance<min_dist) 04977 { 04978 //reset the min_distance 04979 min_dist=distance; 04980 //keep track of which curve is associated with the shortest distance 04981 closest_curve=curve_list[counter2]; 04982 } 04983 } 04984 //find the parent body of the minimum distance curve 04985 BodySM* body_sm = closest_curve->bodysm(); 04986 //append that body to a keep list 04987 keep_bodies_list.append(body_sm); 04988 } 04989 //delete bodies which repeat (useful only when in granite engine) 04990 keep_bodies_list.uniquify_ordered(); 04991 //subtract the keep_list from the webcut_results_list 04992 webcut_results_list -=keep_bodies_list; 04993 //delete webcut_results_list memory 04994 gePtr1->get_gqe()->delete_solid_model_entities(webcut_results_list); 04995 04996 if( CubitUndo::get_undo_enabled() ) 04997 CubitUndo::save_state(); 04998 04999 //builds ref bodies 05000 DLIList<Body*> output_body_list; 05001 if (!sweep_finish("translational", body_list, keep_bodies_list, output_body_list, change_newids)) 05002 { 05003 gePtr1->get_gqe()->delete_solid_model_entities(keep_bodies_list); 05004 status = CUBIT_FAILURE; 05005 } 05006 05007 if( CubitUndo::get_undo_enabled()) 05008 { 05009 if( status == CUBIT_FAILURE ) 05010 CubitUndo::remove_last_undo(); 05011 else 05012 CubitUndo::note_result_bodies( output_body_list ); 05013 } 05014 } 05015 else 05016 { 05017 PRINT_ERROR( "No edge(s) found - sweep creation failed.\n" ); 05018 return CUBIT_FAILURE; 05019 } 05020 05021 return CUBIT_SUCCESS; 05022 } 05023 // Author: Derek Quam 05024 // Dec. 1, 2008 05025 CubitStatus GeometryModifyTool::sweep_surface_target(RefFace *face, 05026 Body *target_body, 05027 CubitVector distance, 05028 CubitPlane stop_plane, 05029 double magnitude) 05030 { 05031 // Declare local variables 05032 Surface *source_surf; 05033 bool set_dist = true, set_plane = true, set_mag = true; 05034 CubitVector direction; 05035 CubitStatus status; 05036 DLIList<Body*> body_list; 05037 DLIList<GeometryEntity*> geom_list; 05038 GeometryModifyEngine* gePtr1 = 0; 05039 CubitBoolean change_newids; 05040 DLIList<RefEntity*> ref_ent_list; 05041 ref_ent_list.append(face); 05042 05043 // Check to make sure the target body is a solid 05044 if (target_body->is_sheet_body()) 05045 { 05046 PRINT_ERROR("Target body must be a solid body.\n"); 05047 return CUBIT_FAILURE; 05048 } 05049 05050 // Set up the sweep 05051 if (!sweep_setup("target", ref_ent_list, body_list, gePtr1, 05052 change_newids, geom_list, false)) 05053 return CUBIT_FAILURE; 05054 05055 // Get the Surface * from the RefFace * 05056 source_surf = face->get_surface_ptr(); 05057 05058 // Check if the direction vector and stop plane were specified 05059 if (distance.length() < 0.0001) 05060 set_dist = false; 05061 if (stop_plane.normal().length() < 0.0001) 05062 set_plane = false; 05063 if (magnitude < 0.0001) 05064 set_mag = false; 05065 05066 // Calculate the direction of the sweep 05067 if (!set_dist) 05068 direction = face->normal_at(face->center_point()); 05069 else 05070 direction = distance; 05071 direction.normalize(); 05072 05073 double length = 0.0; 05074 if (!set_mag && !set_plane) 05075 { 05076 CubitVector center_body = target_body->center_point(); 05077 CubitVector center_face = face->center_point(); 05078 length = center_face.distance_between(center_body); 05079 } 05080 else if (set_plane) 05081 { 05082 length = stop_plane.intersect(face->center_point(), direction).distance_between(face->center_point()); 05083 } 05084 else 05085 { 05086 length = magnitude; 05087 } 05088 if (set_mag && length > magnitude) 05089 length = magnitude; 05090 direction *= length; 05091 05092 DLIList<BodySM*> new_bodies; 05093 status = gePtr1->sweep_to_body(source_surf, target_body->get_body_sm_ptr(), direction, new_bodies ); 05094 05095 if (status != CUBIT_SUCCESS) 05096 return status; 05097 05098 if( CubitUndo::get_undo_enabled() ) 05099 CubitUndo::save_state(); 05100 05101 // Make all the new bodies 05102 DLIList<Body*> output_body_list; 05103 if (!sweep_finish("target", body_list, new_bodies, output_body_list, change_newids)) 05104 status = CUBIT_FAILURE; 05105 05106 if( CubitUndo::get_undo_enabled()) 05107 { 05108 if( status == CUBIT_FAILURE ) 05109 CubitUndo::remove_last_undo(); 05110 else 05111 { 05112 //For some reason the ouput_body_list contains one of the original 05113 //volumes that we do not want to delete when we are performing an 05114 //undo on the sweep. So we remove that original volume from the 05115 //"to undo" list. 05116 Body* to_delete = output_body_list[1]; 05117 output_body_list.clean_out(); 05118 output_body_list.append(to_delete); 05119 CubitUndo::note_result_bodies( output_body_list ); 05120 } 05121 } 05122 05123 /* 05124 for (int i = 0; i < new_bodies.size(); i++) 05125 GeometryQueryTool::instance()->make_Body(new_bodies.get_and_step()); 05126 */ 05127 05128 05129 return CUBIT_SUCCESS; 05130 } 05131 05132 // Author: Andrew Rout and Derek Quam 05133 // Nov. 14, 2008 05134 CubitStatus GeometryModifyTool::sweep_curve_target(DLIList<RefEdge*>& edge_list, 05135 Body *target_body, 05136 DLIList<Body*> &out_bodies, 05137 CubitVector distance, 05138 CubitPlane stop_plane, 05139 bool unite) 05140 { 05141 DLIList<BodySM*> new_bodies; 05142 DLIList<Curve*> curve_list; 05143 bool set_dist = true, set_plane = true; 05144 double larDist = 1.0; 05145 CubitVector dir = distance; 05146 CubitStatus status; 05147 05148 // Check to make sure the target body is a sheetbody 05149 if (!target_body->is_sheet_body()) 05150 { 05151 PRINT_ERROR("Target body must be a sheet body.\n"); 05152 return CUBIT_FAILURE; 05153 } 05154 05155 // Get the Curve *'s from the RefEdge *'s 05156 for (int i = 0; i < edge_list.size(); i++) 05157 { 05158 edge_list[i]->get_curve_ptr()->set_saved_id(edge_list[i]->id()); 05159 curve_list.append(edge_list[i]->get_curve_ptr()); 05160 } 05161 // Check if the direction vector and stop plane were specified 05162 if (distance.length() < 0.0001) 05163 set_dist = false; 05164 if (stop_plane.normal().length() < 0.0001) 05165 set_plane = false; 05166 05167 // Check inputs 05168 if (!set_plane && !set_dist) 05169 { 05170 PRINT_ERROR("User must specify a stop plane, a direction, or both.\n"); 05171 return CUBIT_FAILURE; 05172 } 05173 05174 // Calculate the direction vector 05175 double begDist, midDist, endDist; 05176 for (int i = 0; i < edge_list.size(); i++) 05177 { 05178 CubitVector beg, mid, end, begP, midP, endP; 05179 RefEdge *temp = edge_list.get_and_step(); 05180 05181 // Retrieve the beginning, middle, and end coordinates of the edge 05182 beg = temp->start_coordinates(); 05183 temp->mid_point(mid); 05184 end = temp->end_coordinates(); 05185 05186 if (set_plane) 05187 { 05188 // Project the start, mid, and end point onto the stop plane 05189 begP = stop_plane.project(beg); 05190 midP = stop_plane.project(mid); 05191 endP = stop_plane.project(end); 05192 05193 // Calculate the distance between the points 05194 begDist = beg.distance_between(begP); 05195 midDist = mid.distance_between(midP); 05196 endDist = end.distance_between(endP); 05197 } 05198 else // No stop plane specified 05199 { 05200 begDist = beg.distance_between(target_body->center_point()); 05201 midDist = mid.distance_between(target_body->center_point()); 05202 endDist = end.distance_between(target_body->center_point()); 05203 } 05204 05205 // Find the largest distance 05206 if (begDist > larDist) 05207 larDist = begDist; 05208 if (midDist > larDist) 05209 larDist = midDist; 05210 if (endDist > larDist) 05211 larDist = endDist; 05212 05213 // Make sure the plane normal is pointing the right way 05214 if (set_plane) 05215 { 05216 double planeNorm = stop_plane.normal().interior_angle(beg-begP); 05217 if (planeNorm <= 90 || planeNorm >= 270) 05218 stop_plane.reverse(); 05219 } 05220 05221 if (!set_dist) 05222 dir += (midP-mid); 05223 05224 } // End for loop 05225 if (!set_dist) 05226 dir /= edge_list.size(); 05227 05228 // Unitize the direction vector 05229 dir /= dir.length(); 05230 05231 // Add the magnitude to the direction vector and check for intersection with the stop plane 05232 dir *= larDist; 05233 if (set_plane) 05234 { 05235 double angle = dir.interior_angle(stop_plane.normal()); 05236 if (angle >= 90 && angle <= 270) 05237 PRINT_WARNING("Direction vector does not intersect stop plane!\n"); 05238 } 05239 05240 // Call the geometry function 05241 status = get_gme()->sweep_to_body(curve_list, target_body->get_body_sm_ptr(), dir, new_bodies, unite); 05242 05243 if (status != CUBIT_SUCCESS) 05244 return CUBIT_FAILURE; 05245 05246 // Make all the new bodies 05247 for (int i = 0; i < new_bodies.size(); i++) 05248 { 05249 out_bodies.append(GeometryQueryTool::instance()->make_Body(new_bodies.get_and_step())); 05250 PRINT_INFO("Created volume in body %d\n", out_bodies[i]->id()); 05251 } 05252 05253 return CUBIT_SUCCESS; 05254 } 05255 05256 //Author: Jonathan Bugman 05257 //Sept 10, 2006 05258 CubitStatus GeometryModifyTool::sweep_surface_target(CubitPlane ref_plane, 05259 DLIList<RefEntity*>& ref_ent_list) 05260 { 05261 DLIList<RefFace*> surface_list; 05262 CAST_LIST(ref_ent_list, surface_list, RefFace); 05263 double distance1; 05264 double distance2; 05265 double distance3; 05266 double temp_counter=0; 05267 CubitVector begin_point; 05268 CubitVector target_begin_point; 05269 CubitVector get_mid_point; 05270 CubitVector target_mid_point; 05271 CubitVector end_point; 05272 CubitVector target_end_point; 05273 CubitVector result; 05274 double max_distance_for_edge=0; 05275 CubitVector max_result; 05276 DLIList<RefEdge*> surf_edge_list; 05277 05278 //make sure that only one surface has been selected 05279 if(surface_list.size() == 0) 05280 { 05281 PRINT_ERROR( "No surface found - sweep surface to target failed.\n" ); 05282 return CUBIT_FAILURE; 05283 } 05284 05285 //make sure that there are actually surfaces in list 05286 else if(surface_list.size() > 1) 05287 { 05288 PRINT_ERROR( "You can only use this operation \n with one surface selected at a time\n" ); 05289 return CUBIT_FAILURE; 05290 } 05291 else 05292 { 05293 //this part of the code steps through all edges that could be 05294 //selected by user and finds the largest distance of all edges from three 05295 //points: midpoint, endpoint, and beginpoint 05296 for (int i=0;i<surface_list.size();i++) 05297 { 05298 surface_list[i]->ref_edges(surf_edge_list); 05299 for (int j=0;j<surf_edge_list.size();j++) 05300 { 05301 //get midpoint of edge on surface 05302 surf_edge_list[j]->mid_point(get_mid_point); 05303 //Project the midpoint of each surface edge onto the specified plane 05304 target_mid_point = ref_plane.project(get_mid_point); 05305 05306 //Calculate the distance between the mid_point, and target_point 05307 distance1 = target_mid_point.distance_between(get_mid_point); 05308 05309 //the next two blocks are just copies of the above three steps 05310 05311 int fraction_along_curve = 1; 05312 surf_edge_list[j]->position_from_fraction(fraction_along_curve, end_point); 05313 target_end_point = ref_plane.project(end_point); 05314 distance2 = target_end_point.distance_between(end_point); 05315 05316 fraction_along_curve = 0; 05317 surf_edge_list[j]->position_from_fraction(fraction_along_curve, begin_point); 05318 target_begin_point = ref_plane.project(begin_point); 05319 distance3 = target_begin_point.distance_between(begin_point); 05320 05321 //see which of the three distances is greater of the edge 05322 //and compare its distance to the other edges 05323 if (distance1>distance2 && distance1>distance3) 05324 { 05325 result = 2*(target_mid_point - get_mid_point); 05326 max_distance_for_edge=distance1; 05327 if (max_distance_for_edge>temp_counter) 05328 { 05329 temp_counter = max_distance_for_edge; 05330 max_result=result; 05331 05332 } 05333 } 05334 else if (distance2>distance3) 05335 { 05336 result = 2*(target_end_point - end_point); 05337 max_distance_for_edge=distance2; 05338 if (max_distance_for_edge>temp_counter) 05339 { 05340 temp_counter = max_distance_for_edge; 05341 max_result=result; 05342 05343 } 05344 } 05345 else 05346 { 05347 result = 2*(target_begin_point - begin_point); 05348 max_distance_for_edge=distance3; 05349 if (max_distance_for_edge>temp_counter) 05350 { 05351 temp_counter = max_distance_for_edge; 05352 max_result=result; 05353 05354 } 05355 } 05356 //just checking to make sure the user didn't specify a surface as both 05357 //a target surface and sweeping surface which would result in a CUBIT crash 05358 if (i==surface_list.size()-1 && j==surf_edge_list.size()-1 && 05359 max_distance_for_edge < 0.000000000000001) 05360 { 05361 PRINT_ERROR( "The sweep distance is less than the geometry tolerance\n" ); 05362 PRINT_ERROR( "This may be caused by selecting the same\n"); 05363 PRINT_ERROR( "sweep surface and target surface\n" ); 05364 return CUBIT_FAILURE; 05365 } 05366 } 05367 } 05368 //using the facet edges defined by the drawing geometry code; take the leading 05369 //and trailing edge vectors of each facet edge; With that, calc the dot product 05370 //and if negative (meaning the vector directions switched) the curve travels 05371 //through the plane and the sweep function will fail 05372 surface_list.reset(); 05373 surf_edge_list.clean_out(); 05374 for (int kk=0;kk<surface_list.size();kk++) 05375 { 05376 surface_list[kk]->ref_edges(surf_edge_list); 05377 for (int ii=0;ii<surf_edge_list.size();ii++) 05378 { 05379 Curve *facet_curve; 05380 facet_curve=surf_edge_list[ii]->get_curve_ptr(); 05381 CubitStatus response; 05382 GMem g_mem; 05383 05384 //get number of points and their locations 05385 //on the curve as defined by the drawing geometry algorithm 05386 response = facet_curve->get_geometry_query_engine()-> 05387 get_graphics( facet_curve, &g_mem ); 05388 05389 int num_points = g_mem.pointListCount; 05390 05391 if (response==CUBIT_FAILURE || num_points == 0) 05392 { 05393 PRINT_WARNING("Unable to preview a curve\n" ); 05394 } 05395 05396 GPoint *point_data = g_mem.point_list(); 05397 05398 for (int jj=0; jj < (num_points-1); jj++) 05399 { 05400 //get first points vectors 05401 CubitVector point_1; 05402 point_1.x(point_data[jj].x); 05403 point_1.y(point_data[jj].y); 05404 point_1.z(point_data[jj].z); 05405 //get second points vectors 05406 CubitVector point_2; 05407 point_2.x(point_data[jj+1].x); 05408 point_2.y(point_data[jj+1].y); 05409 point_2.z(point_data[jj+1].z); 05410 //project the two points onto target plane 05411 CubitVector target_point_1; 05412 target_point_1 = ref_plane.project(point_1); 05413 CubitVector target_point_2; 05414 target_point_2 = ref_plane.project(point_2); 05415 //calc vector from point on curve to point on surface 05416 CubitVector vec_1 = point_1 - target_point_1; 05417 CubitVector vec_2 = point_2 - target_point_2; 05418 //make them unit vectors 05419 vec_1.normalize(); 05420 vec_2.normalize(); 05421 //double dot = DotProduct(vec_1,vec_2); 05422 //calculate dot product 05423 double dot = vec_1.x()*vec_2.x()+vec_1.y()*vec_2.y()+vec_1.z()*vec_2.z(); 05424 05425 //check to see if dot product sign is zero 05426 //the and statement checks for if the first or last vertex of the edge 05427 //which may be sitting on the surface, this is alright 05428 //and should still be able to sweep 05429 if (dot<0 && 0<jj && jj<(num_points-2)) 05430 { 05431 PRINT_ERROR( "The surface is traveling through the plane\n" ); 05432 PRINT_ERROR( "and thus forces the sweep direction to switch\n" ); 05433 PRINT_ERROR( "direction. Try splitting the surface.\n" ); 05434 return CUBIT_FAILURE; 05435 } 05436 } 05437 } 05438 } 05439 05440 DLIList<Body*> body_list; 05441 DLIList<GeometryEntity*> geom_list; 05442 GeometryModifyEngine* gePtr1 = 0; 05443 CubitBoolean change_newids; 05444 05445 if (!sweep_setup("translational", ref_ent_list, body_list, gePtr1, 05446 change_newids, geom_list, false )) 05447 return CUBIT_FAILURE; 05448 05449 if( CubitUndo::get_undo_enabled()) 05450 //Faces will get consumed so you have to save out original entities 05451 CubitUndo::save_state_with_cubit_file( surface_list ); 05452 05453 DLIList<BodySM*> sweep_result_list; 05454 05455 //below block is default settings to be fed into sweep_translational 05456 CubitBoolean rigid = CUBIT_FALSE; 05457 CubitBoolean switchside = CUBIT_FALSE; 05458 int draft_type = 0; 05459 double draft_angle=0.0; 05460 05461 //find normal vector to user specified plane 05462 CubitVector vec1 = ref_plane.normal(); 05463 CubitVector vec2; 05464 CubitVector vec3; 05465 //get orthogonal vectors of the normal vector 05466 vec1.orthogonal_vectors(vec2, vec3); 05467 //place the orthogonal vectors at a point on the plane as opposed to the origin 05468 vec2=vec2+target_mid_point; 05469 vec3=vec3+target_mid_point; 05470 DLIList<BodySM*> webcut_results_list; 05471 //get a point on the first user specified surface before it gets consumed in the sweep_translational function 05472 CubitVector mid_point_surface; 05473 mid_point_surface = surface_list[0]->center_point(); 05474 05475 //sweep the curve down through and hopefully past the target surface 05476 CubitStatus status = gePtr1->sweep_translational( geom_list,sweep_result_list, 05477 max_result,draft_angle, draft_type,switchside,rigid,CUBIT_FALSE,CUBIT_FALSE); 05478 05479 if (status == 0) 05480 { 05481 //If in here, sweep_translational failed so delete result_list and 05482 //print an error to the screen for the user 05483 gePtr1->get_gqe()->delete_solid_model_entities(sweep_result_list); 05484 PRINT_ERROR( "Error occured in the sweep operation.\n" ); 05485 05486 if( CubitUndo::get_undo_enabled()) 05487 CubitUndo::remove_last_undo(); 05488 return CUBIT_FAILURE; 05489 } 05490 05491 DLIList<BodySM*> neighbor_imprint_list; 05492 //do a webcut with a plane created from the three projected points 05493 CubitStatus status2 = gePtr1->webcut(sweep_result_list,target_mid_point, 05494 vec2,vec3,neighbor_imprint_list, webcut_results_list); 05495 05496 if (status2 == 0) 05497 { 05498 //If in here, webcut operation failed so delete result_list and 05499 //print an error to the screen for the user 05500 gePtr1->get_gqe()->delete_solid_model_entities(sweep_result_list); 05501 gePtr1->get_gqe()->delete_solid_model_entities(webcut_results_list); 05502 PRINT_ERROR( "Error occured in the webcut operation.\n" ); 05503 05504 if( CubitUndo::get_undo_enabled()) 05505 CubitUndo::remove_last_undo(); 05506 return CUBIT_FAILURE; 05507 } 05508 05509 DLIList<BodySM*> keep_bodies_list = webcut_results_list; 05510 int bodies_deleted_counter=0; 05511 CubitVector target_mid_point_volume; 05512 CubitVector mid_point_volume; 05513 CubitVector target_mid_point_surface; 05514 double volume_size; 05515 05516 //project the mid_point of user specified surface onto target plane 05517 target_mid_point_surface = ref_plane.project(mid_point_surface); 05518 //calculate vector between the two points and then normalize 05519 CubitVector vec_1 = mid_point_surface - target_mid_point_surface; 05520 vec_1.normalize(); 05521 05522 //step through the 05523 for (int counter=0;counter<webcut_results_list.size();counter++) 05524 { 05525 //find the geometric midpoint of the body and project that point on the target plane 05526 webcut_results_list[counter]->mass_properties(mid_point_volume,volume_size); 05527 target_mid_point_volume = ref_plane.project(mid_point_volume); 05528 //generate a vector between the two points and then normalize 05529 CubitVector vec_2 = mid_point_volume - target_mid_point_volume; 05530 vec_2.normalize(); 05531 05532 //calculate the dot product 05533 double dot = vec_1.x()*vec_2.x()+vec_1.y()*vec_2.y()+vec_1.z()*vec_2.z(); 05534 05535 //if a negative dot product delete it because it is on the opposite side of the target plane 05536 if (dot < 0) 05537 { 05538 keep_bodies_list.remove(webcut_results_list[counter]); 05539 bodies_deleted_counter = bodies_deleted_counter + 1; 05540 } 05541 05542 } 05543 05544 //test to see if all bodies have been deleted and if so let the user know 05545 if (bodies_deleted_counter == webcut_results_list.size()) 05546 { 05547 PRINT_ERROR( "All sweeped surfaces deleted - sweep_target failed.\n" ); 05548 PRINT_ERROR( "This may be due to granite engine limitations and/or\n" ); 05549 PRINT_ERROR( "angle between curve and target surface\n" ); 05550 05551 if( CubitUndo::get_undo_enabled()) 05552 CubitUndo::remove_last_undo(); 05553 return CUBIT_FAILURE; 05554 } 05555 05556 //delete webcut_results_list since it is no longer of use 05557 webcut_results_list -= keep_bodies_list; 05558 gePtr1->get_gqe()->delete_solid_model_entities(webcut_results_list); 05559 05560 //builds ref bodies 05561 DLIList<Body*> output_body_list; 05562 if (!sweep_finish("translational", body_list, keep_bodies_list, output_body_list, change_newids)) 05563 status = CUBIT_FAILURE; 05564 05565 if( CubitUndo::get_undo_enabled()) 05566 { 05567 if( status == CUBIT_FAILURE ) 05568 CubitUndo::remove_last_undo(); 05569 else 05570 CubitUndo::note_result_bodies( output_body_list ); 05571 } 05572 05573 } 05574 return CUBIT_SUCCESS; 05575 } 05576 05577 05578 CubitStatus GeometryModifyTool::sweep_perpendicular( DLIList<RefEntity*>& ref_ent_list, 05579 double distance, 05580 double draft_angle, 05581 int draft_type, 05582 CubitBoolean switchside, 05583 CubitBoolean rigid, 05584 CubitBoolean anchor_entity, 05585 CubitBoolean keep_old, 05586 DLIList<Body*>& output_body_list) 05587 { 05588 DLIList<Body*> body_list; 05589 DLIList<GeometryEntity*> geom_list; 05590 GeometryModifyEngine* gePtr1 = 0; 05591 CubitBoolean change_newids; 05592 if (!sweep_setup("translational", ref_ent_list, body_list, gePtr1, 05593 change_newids, geom_list, keep_old)) 05594 return CUBIT_FAILURE; 05595 05596 if( CubitUndo::get_undo_enabled()) 05597 { 05598 DLIList<RefEdge*> edge_list; 05599 DLIList<RefFace*> face_list; 05600 05601 CAST_LIST( ref_ent_list, edge_list, RefEdge ); 05602 CAST_LIST( ref_ent_list, face_list, RefFace ); 05603 05604 //Edges aren't consumed, so there's nothing to save out 05605 if( edge_list.size() || keep_old ) 05606 CubitUndo::save_state(); 05607 else 05608 //Faces will get consumed so you have to save out original entities 05609 CubitUndo::save_state_with_cubit_file( face_list ); 05610 } 05611 05612 DLIList<BodySM*> result_list; 05613 CubitStatus status = gePtr1-> 05614 sweep_perpendicular( geom_list, 05615 result_list, 05616 distance, 05617 draft_angle, 05618 draft_type, 05619 switchside, 05620 rigid, 05621 anchor_entity, 05622 keep_old ); 05623 05624 if( keep_old ) 05625 body_list.clean_out(); 05626 05627 if (!sweep_finish("perpendicular", body_list, result_list, output_body_list, change_newids)) 05628 status = CUBIT_FAILURE; 05629 05630 if( CubitUndo::get_undo_enabled()) 05631 { 05632 if( status == CUBIT_FAILURE ) 05633 CubitUndo::remove_last_undo(); 05634 else 05635 CubitUndo::note_result_bodies( output_body_list ); 05636 } 05637 05638 return status; 05639 } 05640 CubitStatus GeometryModifyTool::sweep_along_curve(DLIList<RefEntity*>& ref_ent_list, 05641 DLIList<RefEdge*>& ref_edge_list, 05642 DLIList<Body*>& output_body_list, 05643 CubitBoolean anchor_entity, 05644 CubitBoolean keep_old, 05645 double draft_angle, 05646 int draft_type, 05647 CubitBoolean rigid) 05648 05649 { 05650 DLIList<GeometryEntity*> geom_list(ref_ent_list.size()); 05651 DLIList<Curve*> curve_list(ref_edge_list.size()); 05652 DLIList<Body*> body_list(ref_ent_list.size()); 05653 GeometryModifyEngine* engine_ptr = 0; 05654 CubitBoolean changed_new_ids = CUBIT_FALSE; 05655 CubitStatus status = sweep_setup( "along_curve", 05656 ref_ent_list, 05657 body_list, 05658 engine_ptr, 05659 changed_new_ids, 05660 geom_list, 05661 keep_old, 05662 &ref_edge_list, 05663 &curve_list ); 05664 if (status != CUBIT_SUCCESS) 05665 return status; 05666 05667 if( CubitUndo::get_undo_enabled()) 05668 { 05669 DLIList<RefEdge*> edge_list; 05670 DLIList<RefFace*> face_list; 05671 05672 CAST_LIST( ref_ent_list, edge_list, RefEdge ); 05673 CAST_LIST( ref_ent_list, face_list, RefFace ); 05674 05675 //Edges aren't consumed, so there's nothing to save out 05676 if( keep_old ) 05677 CubitUndo::save_state(); 05678 else 05679 { 05680 bool free_curves = false; 05681 for( int i=edge_list.size(); i--; ) 05682 { 05683 if( edge_list.get_and_step()->num_parent_ref_entities() == 0 ) 05684 { 05685 free_curves = true; 05686 break; 05687 } 05688 } 05689 05690 DLIList<Body*> bodies_to_save; 05691 DLIList<RefEntity*> free_surfaces; 05692 for( int i=face_list.size(); i--; ) 05693 { 05694 RefFace *ref_face = face_list.get_and_step(); 05695 05696 if( ref_face->num_parent_ref_entities() == 0 ) 05697 free_surfaces.append( ref_face ); 05698 else 05699 bodies_to_save.append_unique( ref_face->ref_volume()->body() ); 05700 } 05701 //Faces will get consumed so you have to save out original entities 05702 if( bodies_to_save.size() || free_surfaces.size() ) 05703 CubitUndo::save_state_with_cubit_file( bodies_to_save, &free_surfaces ); 05704 else if(free_curves ) 05705 CubitUndo::save_state_with_cubit_file( edge_list ); 05706 else 05707 CubitUndo::save_state(); 05708 } 05709 } 05710 05711 DLIList<BodySM*> result_list; 05712 status = engine_ptr->sweep_along_curve( geom_list, 05713 result_list, 05714 curve_list, 05715 draft_angle, 05716 draft_type, 05717 rigid, 05718 anchor_entity, 05719 keep_old); 05720 05721 if( keep_old ) 05722 body_list.clean_out(); 05723 05724 if (!sweep_finish("along_curve", body_list, result_list, output_body_list, changed_new_ids)) 05725 status = CUBIT_FAILURE; 05726 05727 if( CubitUndo::get_undo_enabled()) 05728 { 05729 if( status == CUBIT_FAILURE ) 05730 CubitUndo::remove_last_undo(); 05731 else 05732 CubitUndo::note_result_bodies( output_body_list ); 05733 } 05734 05735 return status; 05736 } 05737 05738 void GeometryModifyTool::initialize_settings() { 05739 05740 05741 SettingHandler::instance()->add_setting("Group Imprint", 05742 GeometryModifyTool::set_group_imprint, 05743 GeometryModifyTool::get_group_imprint); 05744 05745 SettingHandler::instance()->add_setting("NonRegImprint", 05746 GeometryModifyTool::set_all_edges_imprint, 05747 GeometryModifyTool::get_all_edges_imprint); 05748 05749 SettingHandler::instance()->add_setting("New Ids", 05750 GeometryModifyTool::set_new_ids, 05751 GeometryModifyTool::get_new_ids); 05752 05753 SettingHandler::instance()->add_setting("Separate After Webcut", 05754 GeometryModifyTool::set_sep_after_webcut_setting, 05755 GeometryModifyTool::get_sep_after_webcut_setting); 05756 05757 SettingHandler::instance()->add_setting("old names", 05758 GeometryModifyTool::set_old_names, 05759 GeometryModifyTool::get_old_names); 05760 } 05761 05762 05763 05764 // ********** END PUBLIC FUNCTIONS ********** 05765 05766 // ********** BEGIN PROTECTED FUNCTIONS ********** 05767 05768 //------------------------------------------------------------------------- 05769 // Purpose : Constructor of the GeometryModifyTool class. 05770 // 05771 // Special Notes : 05772 // 05773 // Creator : Xuechen Liu 05774 // 05775 // Creation Date : 07/11/96 05776 //------------------------------------------------------------------------- 05777 GeometryModifyTool::GeometryModifyTool(GeometryModifyEngine*gme_ptr) 05778 { 05779 if (gme_ptr) gmeList.append(gme_ptr); 05780 } 05781 05782 //------------------------------------------------------------------------- 05783 // Purpose : This functions webcuts a list of bodies through a plane. 05784 // The newly created bodies are and merged depeding on the 05785 // respective flags. 05786 // 05787 // Special Notes : 05788 // 05789 // Creator : Raikanta Sahu 05790 // 05791 // Creation Date : 12/17/96 05792 //------------------------------------------------------------------------- 05793 05794 CubitStatus GeometryModifyTool::webcut_with_brick( 05795 DLIList<Body*>& webcut_body_list, 05796 const CubitVector ¢er, 05797 const CubitVector axes[3], 05798 const CubitVector &extension, 05799 DLIList<Body*> &results_list, 05800 DLIList<Body*> &neighboring_bodies, 05801 ImprintType imprint_type, 05802 CubitBoolean merge, 05803 CubitBoolean preview) 05804 { 05805 // Make sure that entity creation is possible. Allow at most 05806 // only one of the dimensions to be zero - in which case a planar 05807 // sheet is used to do the cutting. 05808 double width = 2.0*extension.x(); 05809 double height = 2.0*extension.y(); 05810 double depth = 2.0*extension.z(); 05811 if ( width < 0.0 || height < 0.0 || depth < 0.0 ) 05812 { 05813 PRINT_ERROR( "Cannot make a brick of size %f x %f x %f\n" 05814 " Negative dimensions are not allowed.\n", 05815 width, height, depth ); 05816 return CUBIT_FAILURE ; 05817 } 05818 05819 BodySM *cutting_tool_ptr = NULL; 05820 CubitBoolean is_sheet_body = CUBIT_FALSE; 05821 CubitVector p1, p2, p3, p4; 05822 int wz = width < GEOMETRY_RESABS; 05823 int hz = height < GEOMETRY_RESABS; 05824 int dz = depth < GEOMETRY_RESABS; 05825 int num_zero_dim = wz + hz + dz; 05826 if( num_zero_dim > 0 ) 05827 { 05828 if( num_zero_dim > 1 ) 05829 { 05830 PRINT_ERROR( "Cannot make a sheet of size %f x %f x %f\n" 05831 " At least two dimensions must be nonzero.\n", 05832 width, height, depth ); 05833 return CUBIT_FAILURE ; 05834 } 05835 05836 // Make a sheet body instead of a cuboid 05837 CubitVector sheet_axes[2]; 05838 if( wz ) 05839 { 05840 sheet_axes[0] = axes[1]; 05841 sheet_axes[1] = axes[2]; 05842 width = depth; 05843 } 05844 else if( hz ) 05845 { 05846 sheet_axes[0] = axes[2]; 05847 sheet_axes[1] = axes[0]; 05848 height = depth; 05849 } 05850 else 05851 { 05852 sheet_axes[0] = axes[0]; 05853 sheet_axes[1] = axes[1]; 05854 } 05855 05856 // Get the corners of the sheet ready 05857 center.next_point( axes[0], width/2.0, p1 ); 05858 p1.next_point( axes[1], -height/2.0, p1 ); 05859 p1.next_point( axes[1], height, p2 ); 05860 p2.next_point( axes[0], -width, p3 ); 05861 p3.next_point( axes[1], -height, p4 ); 05862 } 05863 05864 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 05865 return CUBIT_FAILURE; 05866 05867 CubitVector tmp_vec( center.x()+width, center.y()+height, center.z()+depth ); 05868 CubitBox tmp_box(tmp_vec); 05869 tmp_vec.set( center.x()-width, center.y()-height, center.z()-depth ); 05870 tmp_box |= tmp_vec; 05871 remove_bodies_outside_bounding_box( webcut_body_list, tmp_box ); 05872 05873 if( webcut_body_list.size() == 0 ) 05874 { 05875 PRINT_INFO("Tool does not intersect any bodies/volumes.\n"); 05876 return CUBIT_FAILURE; 05877 } 05878 05879 if( CubitUndo::get_undo_enabled() ) 05880 { 05881 DLIList<Body*> bodies_to_save; 05882 bodies_to_save += webcut_body_list; 05883 bodies_to_save += neighboring_bodies; 05884 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 05885 } 05886 05887 CubitStatus rval = CUBIT_SUCCESS; 05888 05889 const int count = webcut_body_list.size(); 05890 DLIList<BodySM*> result_sm_list; 05891 DLIList<Body*> body_list(webcut_body_list); 05892 DLIList<BodySM*> engine_body_sms(count); 05893 DLIList<Body*> engine_bodies(count); 05894 GeometryModifyEngine* gme = 0; 05895 05896 while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) ) 05897 { 05898 DLIList<int> merged_surface_ids; 05899 DLIList<int> merged_curve_ids; 05900 DLIList<BodySM*> neighbor_imprint_list; 05901 if (!preview) 05902 { 05903 int i; 05904 for( i=neighboring_bodies.size(); i--; ) 05905 { 05906 Body *neighbor_body = neighboring_bodies.get_and_step(); 05907 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 05908 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 05909 05910 if( gme == neighbor_gme ) 05911 { 05912 neighbor_imprint_list.append( tmp_body ); 05913 engine_bodies.append( neighbor_body ); 05914 } 05915 } 05916 05917 do_attribute_setup(); 05918 DLIList<BodySM*> bodies_to_modify; 05919 bodies_to_modify += engine_body_sms; 05920 bodies_to_modify += neighbor_imprint_list; 05921 push_attributes_before_modify( bodies_to_modify ); 05922 get_merged_curve_and_surface_ids( engine_bodies, merged_surface_ids, merged_curve_ids ); 05923 } 05924 05925 // Create the brick to cut with 05926 if (is_sheet_body) 05927 cutting_tool_ptr = gme->planar_sheet(p1,p2,p3,p4); 05928 else 05929 cutting_tool_ptr = gme->brick( center, axes, extension ); 05930 if( cutting_tool_ptr == NULL ) 05931 return CUBIT_FAILURE; 05932 05933 CubitStatus status = gme->webcut ( 05934 engine_body_sms, cutting_tool_ptr, 05935 neighbor_imprint_list, 05936 result_sm_list, imprint_type, preview ); 05937 05938 // Delete the BodySM that was created to be used as a tool 05939 gme->get_gqe()->delete_solid_model_entities(cutting_tool_ptr) ; 05940 05941 // just continue the loop if previewing 05942 if (preview) 05943 { 05944 rval = status; 05945 continue; 05946 } 05947 05948 restore_vg_after_modify(result_sm_list, engine_bodies, gme); 05949 remove_pushed_attributes(result_sm_list, engine_bodies); 05950 05951 status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list, 05952 &merged_surface_ids, &merged_curve_ids ); 05953 05954 if (!status) 05955 rval = CUBIT_FAILURE; 05956 05957 engine_bodies.clean_out(); 05958 engine_body_sms.clean_out(); 05959 result_sm_list.clean_out(); 05960 } 05961 05962 if (!preview) 05963 do_attribute_cleanup(); 05964 05965 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 05966 { 05967 if( results_list.size() ) //if there are new bodies...something succeeded 05968 CubitUndo::note_result_bodies( results_list ); 05969 else 05970 CubitUndo::remove_last_undo(); 05971 } 05972 05973 return rval; 05974 } 05975 05976 CubitStatus GeometryModifyTool::webcut_with_planar_sheet( 05977 DLIList<Body*>& webcut_body_list, 05978 const CubitVector ¢er, 05979 const CubitVector axes[2], 05980 double width, double height, 05981 DLIList<Body*> &results_list, 05982 DLIList<Body*> &neighboring_bodies, 05983 ImprintType imprint_type, 05984 CubitBoolean merge, 05985 CubitBoolean preview) 05986 { 05987 if ( width <= GEOMETRY_RESABS || height <= GEOMETRY_RESABS ) 05988 { 05989 PRINT_ERROR( "Cannot webcut with a sheet of size %f x %f\n" 05990 " Negative or zero dimensions are not allowed.\n", 05991 width, height ); 05992 return CUBIT_FAILURE ; 05993 } 05994 05995 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 05996 return CUBIT_FAILURE; 05997 05998 CubitStatus rval = CUBIT_SUCCESS; 05999 06000 if( CubitUndo::get_undo_enabled() ) 06001 { 06002 DLIList<Body*> bodies_to_save; 06003 bodies_to_save += webcut_body_list; 06004 bodies_to_save += neighboring_bodies; 06005 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 06006 } 06007 06008 const int count = webcut_body_list.size(); 06009 DLIList<BodySM*> result_sm_list; 06010 DLIList<Body*> body_list(webcut_body_list); 06011 DLIList<BodySM*> engine_body_sms(count); 06012 DLIList<Body*> engine_bodies(count); 06013 GeometryModifyEngine* gme = 0; 06014 06015 while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) ) 06016 { 06017 DLIList<int> merged_surface_ids; 06018 DLIList<int> merged_curve_ids; 06019 DLIList<BodySM*> neighbor_imprint_list; 06020 if (!preview) 06021 { 06022 int i; 06023 for( i=neighboring_bodies.size(); i--; ) 06024 { 06025 Body *neighbor_body = neighboring_bodies.get_and_step(); 06026 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 06027 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 06028 06029 if( gme == neighbor_gme ) 06030 { 06031 neighbor_imprint_list.append( tmp_body ); 06032 engine_bodies.append( neighbor_body ); 06033 } 06034 } 06035 06036 do_attribute_setup(); 06037 DLIList<BodySM*> bodies_sms_to_modify; 06038 bodies_sms_to_modify += engine_body_sms; 06039 bodies_sms_to_modify += neighbor_imprint_list; 06040 push_attributes_before_modify( bodies_sms_to_modify ); 06041 get_merged_curve_and_surface_ids( engine_bodies, merged_surface_ids, merged_curve_ids ); 06042 } 06043 06044 // Create the planar sheet to cut with 06045 CubitVector p1, p2, p3, p4; 06046 06047 // Get the corners of the sheet 06048 center.next_point( axes[0], width/2.0, p1 ); 06049 p1.next_point( axes[1], -height/2.0, p1 ); 06050 p1.next_point( axes[1], height, p2 ); 06051 p2.next_point( axes[0], -width, p3 ); 06052 p3.next_point( axes[1], -height, p4 ); 06053 06054 BodySM *cutting_tool_ptr = gme->planar_sheet(p1,p2,p3,p4); 06055 if( cutting_tool_ptr == NULL ) 06056 return CUBIT_FAILURE; 06057 06058 CubitStatus status = gme->webcut ( 06059 engine_body_sms, cutting_tool_ptr, 06060 neighbor_imprint_list, 06061 result_sm_list, imprint_type, preview ); 06062 06063 // Delete the BodySM that was created to be used as a tool 06064 gme->get_gqe()->delete_solid_model_entities(cutting_tool_ptr) ; 06065 06066 // just continue the loop if previewing 06067 if (preview) 06068 { 06069 rval = status; 06070 continue; 06071 } 06072 06073 restore_vg_after_modify(result_sm_list, engine_bodies, gme); 06074 remove_pushed_attributes(result_sm_list, engine_bodies); 06075 06076 status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list, 06077 &merged_surface_ids, &merged_curve_ids ); 06078 if (!status) 06079 rval = CUBIT_FAILURE; 06080 06081 engine_bodies.clean_out(); 06082 engine_body_sms.clean_out(); 06083 result_sm_list.clean_out(); 06084 } 06085 06086 if (!preview) 06087 do_attribute_cleanup(); 06088 06089 if( preview == CUBIT_FALSE && CubitUndo::get_undo_enabled() ) 06090 { 06091 if( rval == CUBIT_SUCCESS ) 06092 CubitUndo::note_result_bodies( results_list ); 06093 else 06094 CubitUndo::remove_last_undo(); 06095 } 06096 06097 return rval; 06098 } 06099 06100 CubitStatus GeometryModifyTool::webcut_with_plane( 06101 DLIList<Body*>& webcut_body_list, 06102 const CubitVector &vector1, 06103 const CubitVector &vector2, 06104 const CubitVector &vector3, 06105 DLIList<Body*>& results_list, 06106 DLIList<Body*> &neighboring_bodies, 06107 ImprintType imprint_type, 06108 CubitBoolean merge, 06109 CubitBoolean preview) 06110 { 06111 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 06112 return CUBIT_FAILURE; 06113 06114 GfxPreview::clear(); 06115 06116 CubitStatus rval = CUBIT_SUCCESS; 06117 if (preview) 06118 { 06119 GeometryModifyTool::plane_preview(webcut_body_list, vector1, vector2, vector3); 06120 return rval; 06121 } 06122 06123 //remove bodies that won't intersect plane bounding box 06124 remove_bodies_outside_bounding_box( webcut_body_list, vector1, vector2, vector3 ); 06125 06126 if( webcut_body_list.size() == 0 ) 06127 { 06128 PRINT_INFO("Tool does not intersect any bodies/volumes.\n"); 06129 return CUBIT_FAILURE; 06130 } 06131 06132 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 06133 { 06134 DLIList<Body*> bodies_to_save; 06135 bodies_to_save += webcut_body_list; 06136 bodies_to_save += neighboring_bodies; 06137 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 06138 } 06139 06140 const int count = webcut_body_list.size(); 06141 DLIList<BodySM*> temp_sm_list(webcut_body_list.size()); 06142 DLIList<BodySM*> result_sm_list; 06143 DLIList<Body*> body_list(webcut_body_list); 06144 DLIList<BodySM*> engine_body_sms(count); 06145 DLIList<Body*> engine_bodies(count); 06146 GeometryModifyEngine* gme = 0; 06147 06148 // all preview stuff handled before this point 06149 if(!preview) 06150 do_attribute_setup(); 06151 06152 while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) ) 06153 { 06154 06155 //get all the child entities that have been merged 06156 DLIList<int> merged_surface_ids; 06157 DLIList<int> merged_curve_ids; 06158 DLIList<BodySM*> neighbor_imprint_list; 06159 06160 if (!preview) 06161 { 06162 int i; 06163 for( i=neighboring_bodies.size(); i--; ) 06164 { 06165 Body *neighbor_body = neighboring_bodies.get_and_step(); 06166 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 06167 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 06168 06169 if( gme == neighbor_gme ) 06170 { 06171 neighbor_imprint_list.append( tmp_body ); 06172 engine_bodies.append( neighbor_body ); 06173 } 06174 } 06175 06176 DLIList<BodySM*> bodies_sms_to_modify; 06177 bodies_sms_to_modify += engine_body_sms; 06178 bodies_sms_to_modify += neighbor_imprint_list; 06179 push_attributes_before_modify( bodies_sms_to_modify ); 06180 get_merged_curve_and_surface_ids( engine_bodies, merged_surface_ids, merged_curve_ids ); 06181 } 06182 06183 CubitStatus status = gme->webcut(engine_body_sms, vector1, vector2, 06184 vector3, neighbor_imprint_list, result_sm_list, imprint_type, preview ); 06185 06186 if ( status != CUBIT_FAILURE ) 06187 { 06188 if(!preview) 06189 { 06190 restore_vg_after_modify(result_sm_list, engine_bodies, gme); 06191 remove_pushed_attributes(result_sm_list, engine_bodies); 06192 } 06193 status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list, 06194 &merged_surface_ids, &merged_curve_ids ); 06195 } 06196 else 06197 { 06198 if(!preview) 06199 remove_pushed_attributes(result_sm_list, engine_bodies); 06200 } 06201 06202 engine_bodies.clean_out(); 06203 engine_body_sms.clean_out(); 06204 result_sm_list.clean_out(); 06205 06206 if ( status == CUBIT_FAILURE ) 06207 { 06208 rval = CUBIT_FAILURE; 06209 break; 06210 } 06211 } 06212 06213 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 06214 { 06215 if( rval == CUBIT_SUCCESS ) 06216 CubitUndo::note_result_bodies( results_list ); 06217 else 06218 CubitUndo::remove_last_undo(); 06219 } 06220 06221 if(!preview) 06222 do_attribute_cleanup(); 06223 06224 return rval; 06225 } 06226 06227 void GeometryModifyTool::remove_pushed_attributes(DLIList<BodySM*> &new_sms, 06228 DLIList<Body*> &old_bodies) 06229 { 06230 DLIList<TopologyBridge*> old_bridges(old_bodies.size()); 06231 DLIList<TopologyBridge*> new_bridges(new_sms.size()); 06232 CAST_LIST(new_sms, new_bridges, TopologyBridge); 06233 06234 // Get bridges for all of the old Bodies. 06235 int k; 06236 for(k = old_bodies.size(); k>0; k--) 06237 { 06238 Body *body = old_bodies.get_and_step(); 06239 TopologyBridge *tb = body->bridge_manager()->topology_bridge(); 06240 if(tb) 06241 { 06242 old_bridges.append(tb); 06243 DLIList<TopologyBridge*> bridge_list; 06244 bridge_list.append(tb); 06245 // Add any bodies with composites to the new_sms list so that 06246 // make_Body gets called on them. This will make sure that the 06247 // virtual gets ref entities properly built. 06248 if(this->contains_composites(bridge_list)) 06249 { 06250 BodySM *bsm = dynamic_cast<BodySM*>(tb); 06251 if(bsm) 06252 new_sms.append_unique(bsm); 06253 } 06254 } 06255 } 06256 06257 // Make a list including all of the bridges passed in. 06258 DLIList<TopologyBridge*> all_bridges; 06259 all_bridges = new_bridges; 06260 for(k=old_bridges.size(); k--;) 06261 all_bridges.append_unique(old_bridges.get_and_step()); 06262 06263 06264 //Remove ENTITY_ID attributes off non-virtual entities 06265 DLIList<CubitSimpleAttrib> list; 06266 for( k=all_bridges.size(); k--; ) 06267 { 06268 TopologyBridge *top_bridge = all_bridges.get_and_step(); 06269 GeometryModifyEngine *gme = get_engine(top_bridge); 06270 DLIList<TopologyBridge*> children; 06271 gme->get_possible_invalid_tbs(all_bridges, children); 06272 06273 for( int j=children.size(); j--; ) 06274 { 06275 TopologyBridge *tmp_bridge = children.get_and_step(); 06276 if( !GeometryQueryTool::instance()->is_intermediate_geometry( tmp_bridge ) ) 06277 { 06278 tmp_bridge->get_simple_attribute( "ENTITY_ID", list ); 06279 while( list.size() ) 06280 tmp_bridge->remove_simple_attribute_virt(list.pop()); 06281 } 06282 } 06283 } 06284 06285 // At this point we don't need any more attributes on the underlying 06286 // entities so make sure they are cleaned up. 06287 GeometryQueryTool::instance()->ige_remove_attributes( all_bridges ); 06288 } 06289 06290 CubitStatus GeometryModifyTool::restore_vg_after_modify(DLIList<BodySM*> &new_sms, 06291 DLIList<Body*> &old_bodies, 06292 GeometryModifyEngine *gme) 06293 { 06294 DLIList<TopologyBridge*> old_bridges(old_bodies.size()); 06295 DLIList<TopologyBridge*> new_bridges(new_sms.size()); 06296 CAST_LIST(new_sms, new_bridges, TopologyBridge); 06297 06298 // Get bridges for all of the old Bodies. 06299 int k; 06300 for(k = old_bodies.size(); k>0; k--) 06301 { 06302 Body *body = old_bodies.get_and_step(); 06303 TopologyBridge *tb = body->bridge_manager()->topology_bridge(); 06304 if(tb) 06305 { 06306 old_bridges.append(tb); 06307 DLIList<TopologyBridge*> bridge_list; 06308 bridge_list.append(tb); 06309 // Add any bodies with composites to the new_sms list so that 06310 // make_Body gets called on them. This will make sure that the 06311 // virtual gets ref entities properly built. 06312 if(this->contains_composites(bridge_list)) 06313 { 06314 BodySM *bsm = dynamic_cast<BodySM*>(tb); 06315 if(bsm) 06316 new_sms.append_unique(bsm); 06317 } 06318 } 06319 } 06320 06321 // Make a list including all of the bridges passed in. 06322 DLIList<TopologyBridge*> all_bridges; 06323 all_bridges = new_bridges; 06324 for(k=old_bridges.size(); k--;) 06325 all_bridges.append_unique(old_bridges.get_and_step()); 06326 06327 DLIList<TopologyBridge*> tbs_to_check; 06328 if(gme) 06329 gme->get_possible_invalid_tbs(all_bridges, tbs_to_check); 06330 06331 DLIList<Surface*> all_surfs; 06332 DLIList<Curve*> all_curves; 06333 DLIList<TBPoint*> all_points; 06334 if(tbs_to_check.size() > 0) 06335 { 06336 for(k=tbs_to_check.size(); k--;) 06337 { 06338 TopologyBridge *tb = tbs_to_check.get_and_step(); 06339 Surface *surf = dynamic_cast<Surface*>(tb); 06340 if(surf) 06341 all_surfs.append(surf); 06342 else 06343 { 06344 Curve *cur = dynamic_cast<Curve*>(tb); 06345 if(cur) 06346 all_curves.append(cur); 06347 else 06348 { 06349 TBPoint *pt = dynamic_cast<TBPoint*>(tb); 06350 if(pt) 06351 all_points.append(pt); 06352 } 06353 } 06354 } 06355 } 06356 06357 // This function has been changed to blown away any virtual (really only doing 06358 // composites right now). The virtual will rebuilt from the attributes stored 06359 // on the entities. 06360 GeometryQueryTool::instance()->ige_remove_modified(all_surfs, all_curves, all_points); 06361 06362 //Restore virtual 06363 GeometryQueryTool::instance()->ige_import_geom( all_bridges ); 06364 06365 return CUBIT_SUCCESS; 06366 } 06367 06368 GeometryModifyEngine* GeometryModifyTool::group_bodies_by_engine( 06369 DLIList<Body*>& remaining_bodies, 06370 DLIList<Body*>& engine_bodies, 06371 DLIList<BodySM*>& engine_body_sms ) const 06372 { 06373 int i = remaining_bodies.size(); 06374 remaining_bodies.reset(); 06375 GeometryModifyEngine* engine = 0; 06376 06377 if (i == 0) 06378 return 0; 06379 06380 // Skip over any bodies that don't have a modify engine. 06381 while (i--) 06382 { 06383 Body* body = remaining_bodies.get(); 06384 TopologyBridge* bridge = 0; 06385 engine = get_engine(body, &bridge); 06386 if (engine) 06387 { 06388 remaining_bodies.change_to(0); 06389 engine_bodies.append(body); 06390 engine_body_sms.append(dynamic_cast<BodySM*>(bridge)); 06391 remaining_bodies.step(); 06392 break; 06393 } 06394 remaining_bodies.step(); 06395 } 06396 06397 // catch case where no engine was found 06398 if (0 == engine) 06399 { 06400 PRINT_WARNING("No geometry modify engine found for this operation."); 06401 return engine; 06402 } 06403 06404 06405 // Get remaining bodies with same modify engine. 06406 while (i--) 06407 { 06408 Body* body = remaining_bodies.get(); 06409 TopologyBridge* bridge = 0; 06410 if (get_engine(body, &bridge) == engine) 06411 { 06412 remaining_bodies.change_to(0); 06413 engine_bodies.append(body); 06414 engine_body_sms.append(dynamic_cast<BodySM*>(bridge)); 06415 } 06416 remaining_bodies.step(); 06417 } 06418 06419 remaining_bodies.remove_all_with_value(0); 06420 return engine; 06421 } 06422 06423 06424 06425 06426 // ********** END PRIVATE FUNCTIONS ********** 06427 06428 // ********** BEGIN HELPER CLASSES ********** 06429 // ********** END HELPER CLASSES ********** 06430 06431 // ********** BEGIN EXTERN FUNCTIONS ********** 06432 // ********** END EXTERN FUNCTIONS ********** 06433 06434 // ********** BEGIN STATIC FUNCTIONS ********** 06435 // ********** END STATIC FUNCTIONS ********** 06436 06437 CubitStatus GeometryModifyTool::unite( DLIList<BodySM*> &body_sm_list, 06438 DLIList<BodySM*> &new_body_sm_list, 06439 bool keep_old) 06440 { 06441 //this assumes that all bodies have the same modify engine 06442 GeometryModifyEngine *gme = get_engine( body_sm_list.get() ); 06443 CubitStatus result = gme->unite(body_sm_list, new_body_sm_list, keep_old); 06444 return result; 06445 } 06446 06447 CubitStatus 06448 GeometryModifyTool::unite( DLIList<Body*> &bodies, 06449 DLIList<Body*> &new_body_list, 06450 bool keep_old ) 06451 { 06452 if( bodies.size() <= 1 ) 06453 { 06454 PRINT_WARNING("There is only one volume in the list. Nothing modified.\n"); 06455 return CUBIT_FAILURE; 06456 } 06457 if (!okay_to_modify( bodies, "UNITE" )) 06458 return CUBIT_FAILURE; 06459 06460 int i; 06461 const int count = bodies.size(); 06462 DLIList<TopologyEntity*> entity_list(count); 06463 DLIList<TopologyBridge*> bridge_list(count); 06464 bodies.reset(); 06465 for (i = bodies.size(); i--; ) 06466 entity_list.append_unique(bodies.get_and_step()); 06467 GeometryModifyEngine* gme = common_modify_engine( entity_list, bridge_list ); 06468 06469 if( !gme ) 06470 { 06471 PRINT_ERROR("Performing UNITE with volumes containing geometry from\n" 06472 "different modeling engines is not allowed.\n" 06473 "Delete uncommon geometry on these volumes before operation.\n\n"); 06474 return CUBIT_FAILURE; 06475 } 06476 06477 // Cubit can't mesh mixed sheet/solid bodies that are united together. If 06478 // required, separate the unite between these types. 06479 CubitStatus result; 06480 if( GeometryModifyTool::instance()->unite_mixed_models() ) 06481 result = unite_all( gme, bodies, new_body_list, keep_old ); 06482 else 06483 result = unite_separately( gme, bodies, new_body_list, keep_old ); 06484 06485 if( result == CUBIT_FAILURE ) 06486 PRINT_ERROR("UNITE failed\n"); 06487 06488 return result; 06489 } 06490 06491 CubitStatus 06492 GeometryModifyTool::unite_separately( GeometryModifyEngine *gme_ptr, 06493 DLIList<Body*> &bodies, 06494 DLIList<Body*> &new_body_list, 06495 bool keep_old ) 06496 { 06497 // Cubit can't mesh mixed sheet/solid bodies that are united together. Sort 06498 // based on these types. 06499 int i; 06500 Body *body_ptr; 06501 DLIList<Body*> solid_body_list; 06502 DLIList<Body*> sheet_body_list; 06503 bodies.reset(); 06504 for( i=bodies.size(); i--; ) 06505 { 06506 body_ptr = bodies.get_and_step(); 06507 06508 if( body_ptr->is_sheet_body() ) 06509 sheet_body_list.append( body_ptr ); 06510 else 06511 solid_body_list.append( body_ptr ); 06512 } 06513 06514 if( sheet_body_list.size() == 1 && solid_body_list.size() == 1 ) 06515 { 06516 PRINT_ERROR( "Cannot unite solid and sheet bodies together\n" ); 06517 return CUBIT_FAILURE; 06518 } 06519 06520 // Setup undo 06521 if( CubitUndo::get_undo_enabled() ) 06522 { 06523 if( keep_old ) 06524 CubitUndo::save_state(); 06525 else 06526 CubitUndo::save_state_with_cubit_file( bodies ); 06527 } 06528 06529 // Unite solids with each other, and sheets with each other separately 06530 CubitStatus result1 = CUBIT_SUCCESS; 06531 CubitStatus result2 = CUBIT_SUCCESS; 06532 if( solid_body_list.size() > 1 ) 06533 result1 = unite_private( gme_ptr, solid_body_list, new_body_list, keep_old ); 06534 if( sheet_body_list.size() > 1 ) 06535 result2 = unite_private( gme_ptr, sheet_body_list, new_body_list, keep_old ); 06536 06537 // Finish undo 06538 if( CubitUndo::get_undo_enabled() ) 06539 { 06540 if( new_body_list.size() ) 06541 CubitUndo::note_result_bodies( new_body_list ); 06542 else 06543 CubitUndo::remove_last_undo(); 06544 } 06545 06546 // Return success if both unites successful 06547 if( result1 == CUBIT_SUCCESS && result2 == CUBIT_SUCCESS ) 06548 return CUBIT_SUCCESS; 06549 06550 // Return success if either unite was successful 06551 if( ( solid_body_list.size() > 1 && result1 == CUBIT_SUCCESS ) || 06552 ( sheet_body_list.size() > 1 && result2 == CUBIT_SUCCESS ) ) 06553 { 06554 // Give warning if one or the other failed 06555 if( result1 == CUBIT_FAILURE ) 06556 PRINT_WARNING( "Unite of solid volumes failed\n" ); 06557 if( result2 == CUBIT_FAILURE ) 06558 PRINT_WARNING( "Unite of sheet bodies failed\n" ); 06559 06560 return CUBIT_SUCCESS; 06561 } 06562 06563 return CUBIT_FAILURE; 06564 } 06565 06566 CubitStatus 06567 GeometryModifyTool::unite_all( GeometryModifyEngine *gme_ptr, 06568 DLIList<Body*> &bodies, 06569 DLIList<Body*> &new_body_list, 06570 bool keep_old ) 06571 { 06572 // Setup undo 06573 if( CubitUndo::get_undo_enabled() ) 06574 { 06575 if( keep_old ) 06576 CubitUndo::save_state(); 06577 else 06578 CubitUndo::save_state_with_cubit_file( bodies ); 06579 } 06580 06581 // Unite solids with each other, and sheets with each other separately 06582 CubitStatus result = unite_private( gme_ptr, bodies, new_body_list, keep_old ); 06583 06584 // Finish undo 06585 if( CubitUndo::get_undo_enabled() ) 06586 { 06587 if( new_body_list.size() ) 06588 CubitUndo::note_result_bodies( new_body_list ); 06589 else 06590 CubitUndo::remove_last_undo(); 06591 } 06592 06593 return result; 06594 } 06595 06596 // Private workhorse function for unite 06597 CubitStatus 06598 GeometryModifyTool::unite_private( GeometryModifyEngine *gme_ptr, 06599 DLIList<Body*> &body_list, 06600 DLIList<Body*> &new_body_list, 06601 bool keep_old ) 06602 { 06603 if( !body_list.size() ) 06604 return CUBIT_SUCCESS; 06605 06606 int i, j; 06607 Body *body_ptr; 06608 CubitStatus result; 06609 06610 // Give 1st body all the names of all bodies being united 06611 std::list<CubitString> names_list; 06612 DLIList<CubitString> entity_names; 06613 06614 body_list.reset(); 06615 for( i=body_list.size(); i--; ) 06616 { 06617 body_ptr = body_list.get_and_step(); 06618 06619 // See if body has names 06620 if( body_ptr->num_names() ) 06621 { 06622 // Put the names in a list 06623 body_ptr->entity_names( entity_names ); 06624 entity_names.reset(); 06625 06626 // Loop through names 06627 for( j=entity_names.size(); j--; ) 06628 names_list.push_back( entity_names.get_and_step() ); 06629 06630 entity_names.clean_out(); 06631 body_ptr->remove_entity_names(); 06632 } 06633 } 06634 06635 do_attribute_setup(); 06636 06637 DLIList<TopologyEntity*> entity_list(body_list.size()); 06638 DLIList<TopologyBridge*> bridge_list(body_list.size()); 06639 body_list.reset(); 06640 for( i=body_list.size(); i--; ) 06641 entity_list.append_unique(body_list.get_and_step()); 06642 common_modify_engine( entity_list, bridge_list ); 06643 06644 DLIList<BodySM*> body_sm_list(body_list.size()); 06645 CAST_LIST(bridge_list, body_sm_list, BodySM); 06646 06647 push_attributes_before_modify(body_sm_list); 06648 06649 DLIList<int> merged_surface_ids; 06650 DLIList<int> merged_curve_ids; 06651 06652 get_merged_curve_and_surface_ids( body_list, merged_surface_ids, merged_curve_ids ); 06653 06654 DLIList<BodySM*> new_body_sm_list; 06655 result = unite( body_sm_list, new_body_sm_list, keep_old ); 06656 06657 restore_vg_after_modify( new_body_sm_list, body_list, gme_ptr ); 06658 remove_pushed_attributes( new_body_sm_list, body_list ); 06659 06660 DLIList<Body*> result_list; 06661 if( !finish_sm_op(body_list, new_body_sm_list, result_list) ) 06662 result = CUBIT_FAILURE; 06663 06664 if( keep_old == CUBIT_FALSE ) 06665 fixup_merged_entities( merged_surface_ids, merged_curve_ids ); 06666 06667 do_attribute_cleanup(); 06668 06669 if( result ) 06670 { 06671 new_body_list += result_list; 06672 06673 for( j=result_list.size(); j--; ) 06674 { 06675 //Add names to 1st body 06676 std::list<CubitString>::iterator iter, end = names_list.end(); 06677 for (iter = names_list.begin(); iter != end; ++iter) 06678 result_list.get_and_step()->entity_name( *iter ); 06679 } 06680 } 06681 06682 return result; 06683 } 06684 06685 CubitStatus GeometryModifyTool::chop( DLIList<Body*> &bodies, 06686 DLIList<Body*> &intersectBodies, 06687 DLIList<Body*> &outsideBodies, 06688 Body*& leftoversBody, 06689 bool keep_old, 06690 bool nonreg ) 06691 { 06692 leftoversBody = 0; 06693 if (bodies.size() <= 1) 06694 { 06695 PRINT_WARNING("There is only one body in the list. Nothing modified\n"); 06696 return CUBIT_FAILURE; 06697 } 06698 if (!okay_to_modify( bodies, "CHOP" )) 06699 return CUBIT_FAILURE; 06700 06701 int i; 06702 const int count = bodies.size(); 06703 DLIList<Body*> original_body_list = bodies; 06704 DLIList<TopologyEntity*> entity_list(count); 06705 DLIList<TopologyBridge*> bridge_list(count); 06706 bodies.reset(); 06707 for (i = bodies.size(); i--; ) 06708 entity_list.append_unique(bodies.get_and_step()); 06709 GeometryModifyEngine* gme = common_modify_engine( entity_list, bridge_list ); 06710 06711 if ( !gme ) 06712 { 06713 PRINT_ERROR("Performing CHOP with volumes containing geometry\n" 06714 " from different modeling engines is not allowed.\n" 06715 "Delete uncommon geometry on these volumes before operation.\n\n"); 06716 return CUBIT_FAILURE; 06717 } 06718 06719 DLIList<BodySM*> body_sm_list; 06720 CAST_LIST( bridge_list, body_sm_list, BodySM ); 06721 DLIList<BodySM*> intersect_bodies, outside_bodies; 06722 BodySM *leftovers_body = 0; 06723 06724 if( CubitUndo::get_undo_enabled() ) 06725 { 06726 if( keep_old ) 06727 CubitUndo::save_state(); 06728 else 06729 { 06730 //Get all the bodies associated with the vertex 06731 CubitUndo::save_state_with_cubit_file( bodies ); 06732 } 06733 } 06734 06735 DLIList<int> merged_surface_ids; 06736 DLIList<int> merged_curve_ids; 06737 DLIList<Body*> tmp_bodies(1); 06738 tmp_bodies.append( bodies.get() ); 06739 if( keep_old == CUBIT_FALSE ) 06740 get_merged_curve_and_surface_ids( tmp_bodies, merged_surface_ids, merged_curve_ids ); 06741 06742 do_attribute_setup(); 06743 06744 // Push attributes down onto the blank body (first one in list). 06745 DLIList<BodySM*> tmp_body_sm_list; 06746 body_sm_list.reset(); 06747 tmp_body_sm_list.append(body_sm_list.get()); 06748 push_attributes_before_modify(tmp_body_sm_list); 06749 06750 CubitStatus result = gme->chop( body_sm_list, intersect_bodies, 06751 outside_bodies, leftovers_body, keep_old, nonreg ); 06752 06753 if( result == CUBIT_FAILURE ) 06754 { 06755 if( CubitUndo::get_undo_enabled() ) 06756 CubitUndo::remove_last_undo(); 06757 06758 PRINT_ERROR("CHOP failed\n"); 06759 remove_pushed_attributes(tmp_body_sm_list, tmp_bodies); 06760 do_attribute_cleanup(); 06761 return CUBIT_FAILURE; 06762 } 06763 06764 DLIList<BodySM*> all_sms = intersect_bodies; 06765 all_sms += outside_bodies; 06766 06767 restore_vg_after_modify(all_sms, tmp_bodies, gme); 06768 remove_pushed_attributes(all_sms, tmp_bodies); 06769 06770 DLIList<Body*> result_bodies; 06771 06772 body_sm_list.clean_out(); 06773 body_sm_list += intersect_bodies; 06774 06775 CubitStatus stat = finish_sm_op(bodies, body_sm_list, result_bodies); 06776 06777 if( CubitUndo::get_undo_enabled() ) 06778 { 06779 if( stat == CUBIT_SUCCESS ) 06780 CubitUndo::note_result_bodies( result_bodies ); 06781 else 06782 CubitUndo::remove_last_undo(); 06783 } 06784 06785 if( stat == CUBIT_FAILURE ) 06786 { 06787 if( CubitUndo::get_undo_enabled() ) 06788 CubitUndo::remove_last_undo(); 06789 06790 PRINT_ERROR("CHOP failed\n"); 06791 do_attribute_cleanup(); 06792 return CUBIT_FAILURE; 06793 } 06794 intersectBodies += result_bodies; 06795 bodies.clean_out(); 06796 06797 body_sm_list.clean_out(); 06798 body_sm_list += outside_bodies; 06799 result_bodies.clean_out(); 06800 if (!finish_sm_op(bodies, body_sm_list, result_bodies)) 06801 { 06802 if( CubitUndo::get_undo_enabled() ) 06803 CubitUndo::remove_last_undo(); 06804 06805 PRINT_ERROR("CHOP failed\n"); 06806 do_attribute_cleanup(); 06807 return CUBIT_FAILURE; 06808 } 06809 outsideBodies += result_bodies; 06810 06811 if( leftovers_body ) 06812 { 06813 body_sm_list.clean_out(); 06814 body_sm_list.append( leftovers_body ); 06815 result_bodies.clean_out(); 06816 if (!finish_sm_op(bodies, body_sm_list, result_bodies)) 06817 { 06818 if( CubitUndo::get_undo_enabled() ) 06819 CubitUndo::remove_last_undo(); 06820 06821 PRINT_ERROR("CHOP failed\n"); 06822 do_attribute_cleanup(); 06823 return CUBIT_FAILURE; 06824 } 06825 leftoversBody = result_bodies.get(); 06826 06827 } 06828 06829 if( keep_old == CUBIT_FALSE ) 06830 fixup_merged_entities( merged_surface_ids, merged_curve_ids); 06831 06832 if( CubitUndo::get_undo_enabled() ) 06833 { 06834 if( leftoversBody ) 06835 { 06836 DLIList<Body*> tmp_list(1); 06837 tmp_list.append( leftoversBody ); 06838 CubitUndo::note_result_bodies( tmp_list ); 06839 } 06840 CubitUndo::note_result_bodies( intersectBodies ); 06841 CubitUndo::note_result_bodies( outsideBodies ); 06842 } 06843 06844 do_attribute_cleanup(); 06845 return CUBIT_SUCCESS; 06846 } 06847 06848 CubitStatus GeometryModifyTool::hollow( DLIList<Body*>& bodies, 06849 DLIList<RefFace*> faces_to_remove, 06850 DLIList<Body*>& new_bodies, 06851 double depth) 06852 { 06853 if (bodies.size() <= 0 || faces_to_remove.size() <= 0) 06854 { 06855 PRINT_WARNING("Needs at least one body and one face. Nothing modified\n"); 06856 return CUBIT_FAILURE; 06857 } 06858 06859 if (!okay_to_modify( bodies, "HOLLOW" )) 06860 return CUBIT_FAILURE; 06861 06862 // Get the GeometryEngine for each Body of the list to check 06863 // if they are the same and if they are GeometryModifyEngine 06864 06865 const int count = bodies.size(); 06866 DLIList<TopologyEntity*> entity_list(count); 06867 DLIList<TopologyBridge*> bridge_list(count); 06868 CAST_LIST_TO_PARENT(bodies, entity_list); 06869 GeometryModifyEngine* gme = common_modify_engine( entity_list, bridge_list ); 06870 06871 if (!gme) 06872 { 06873 PRINT_ERROR("Performing THICKEN with volumes containing geometry\n" 06874 " from different modeling engines is not allowed.\n" 06875 "Delete uncommon geometry on these volumes before operation.\n\n"); 06876 return CUBIT_FAILURE; 06877 } 06878 06879 DLIList<BodySM*> new_sms(count); 06880 DLIList<BodySM*> body_sms(count); 06881 CAST_LIST(bridge_list, body_sms, BodySM); 06882 06883 if( CubitUndo::get_undo_enabled() ) 06884 { 06885 CubitUndo::save_state_with_cubit_file( bodies ); 06886 } 06887 06888 DLIList <Surface*> surfs_to_remove; 06889 for(int i = 0 ; i < faces_to_remove.size(); i++) 06890 { 06891 Surface* surf = faces_to_remove.get_and_step()->get_surface_ptr(); 06892 if(surf) 06893 surfs_to_remove.append(surf); 06894 } 06895 06896 06897 DLIList<int> merged_surface_ids; 06898 DLIList<int> merged_curve_ids; 06899 get_merged_curve_and_surface_ids( bodies, merged_surface_ids, merged_curve_ids ); 06900 do_attribute_setup(); 06901 06902 // Push attributes down onto the bodies to be hollowed 06903 push_attributes_before_modify( body_sms ); 06904 06905 CubitStatus result = gme->hollow( body_sms, surfs_to_remove, new_sms, depth); 06906 06907 if( result == CUBIT_FAILURE ) 06908 { 06909 if( CubitUndo::get_undo_enabled() ) 06910 CubitUndo::remove_last_undo(); 06911 06912 PRINT_ERROR("Hollow failed\n"); 06913 remove_pushed_attributes(body_sms, bodies); 06914 do_attribute_cleanup(); 06915 return CUBIT_FAILURE; 06916 } 06917 06918 // check for resued entities, they have been moved and we need to notify observers 06919 DLIList<RefEntity*> entities_to_update; 06920 int i; 06921 for(i=0; i<new_sms.size(); i++) 06922 { 06923 BodySM* bodysm = new_sms.get_and_step(); 06924 DLIList<TopologyBridge*> to_check; 06925 DLIList<TopologyBridge*> tmp; 06926 DLIList<Surface*> surfs; 06927 bodysm->surfaces(surfs); 06928 DLIList<Curve*> curves; 06929 bodysm->curves(curves); 06930 DLIList<TBPoint*> points; 06931 bodysm->points(points); 06932 to_check.append(bodysm); 06933 to_check.append(bodysm->lump()); 06934 CAST_LIST_TO_PARENT(surfs, tmp); 06935 to_check += tmp; 06936 CAST_LIST_TO_PARENT(curves, tmp); 06937 to_check += tmp; 06938 CAST_LIST_TO_PARENT(points, tmp); 06939 to_check += tmp; 06940 06941 int k; 06942 for(k=0; k<to_check.size(); k++) 06943 if(BridgeManager* m = to_check.get_and_step()->bridge_manager()) 06944 if(TopologyEntity* t = m->topology_entity()) 06945 entities_to_update.append(CAST_TO(t, RefEntity)); 06946 06947 } 06948 06949 restore_vg_after_modify( new_sms, bodies, gme ); 06950 remove_pushed_attributes( new_sms, bodies ); 06951 06952 result = finish_sm_op(bodies, new_sms, new_bodies); 06953 fixup_merged_entities( merged_surface_ids, merged_curve_ids); 06954 06955 if (CUBIT_FAILURE == result) { 06956 if( CubitUndo::get_undo_enabled() ) 06957 CubitUndo::remove_last_undo(); 06958 06959 PRINT_ERROR("Hollow failed\n"); 06960 do_attribute_cleanup(); 06961 return CUBIT_FAILURE; 06962 } 06963 else if( CubitUndo::get_undo_enabled() ) { 06964 CubitUndo::note_result_bodies( new_bodies ); 06965 } 06966 06967 do_attribute_cleanup(); 06968 return CUBIT_SUCCESS; 06969 } 06970 06971 CubitStatus GeometryModifyTool::thicken( DLIList<Body*>& bodies, 06972 DLIList<Body*>& new_bodies, 06973 double depth, 06974 bool both ) 06975 { 06976 if (bodies.size() <= 0) 06977 { 06978 PRINT_WARNING("There is only one body in the list. Nothing modified\n"); 06979 return CUBIT_FAILURE; 06980 } 06981 06982 if (!okay_to_modify( bodies, "THICKEN" )) 06983 return CUBIT_FAILURE; 06984 06985 // Get the GeometryEngine for each Body of the list to check 06986 // if they are the same and if they are GeometryModifyEngine 06987 06988 const int count = bodies.size(); 06989 DLIList<TopologyEntity*> entity_list(count); 06990 DLIList<TopologyBridge*> bridge_list(count); 06991 CAST_LIST_TO_PARENT(bodies, entity_list); 06992 GeometryModifyEngine* gme = common_modify_engine( entity_list, bridge_list ); 06993 06994 if (!gme) 06995 { 06996 PRINT_ERROR("Performing THICKEN with volumes containing geometry\n" 06997 " from different modeling engines is not allowed.\n" 06998 "Delete uncommon geometry on these volumes before operation.\n\n"); 06999 return CUBIT_FAILURE; 07000 } 07001 07002 if( CubitUndo::get_undo_enabled() ) 07003 CubitUndo::save_state_with_cubit_file( bodies ); 07004 07005 DLIList<BodySM*> new_sms(count); 07006 DLIList<BodySM*> body_sms(count); 07007 CAST_LIST(bridge_list, body_sms, BodySM); 07008 CubitStatus result = gme->thicken( body_sms, new_sms, depth, both); 07009 07010 // check for resued entities, they have been moved and we need to notify observers 07011 DLIList<RefEntity*> entities_to_update; 07012 int i; 07013 for(i=0; i<new_sms.size(); i++) 07014 { 07015 BodySM* bodysm = new_sms.get_and_step(); 07016 DLIList<TopologyBridge*> to_check; 07017 DLIList<TopologyBridge*> tmp; 07018 DLIList<Surface*> surfs; 07019 bodysm->surfaces(surfs); 07020 DLIList<Curve*> curves; 07021 bodysm->curves(curves); 07022 DLIList<TBPoint*> points; 07023 bodysm->points(points); 07024 to_check.append(bodysm); 07025 to_check.append(bodysm->lump()); 07026 CAST_LIST_TO_PARENT(surfs, tmp); 07027 to_check += tmp; 07028 CAST_LIST_TO_PARENT(curves, tmp); 07029 to_check += tmp; 07030 CAST_LIST_TO_PARENT(points, tmp); 07031 to_check += tmp; 07032 07033 int k; 07034 for(k=0; k<to_check.size(); k++) 07035 if(BridgeManager* m = to_check.get_and_step()->bridge_manager()) 07036 if(TopologyEntity* t = m->topology_entity()) 07037 entities_to_update.append(CAST_TO(t, RefEntity)); 07038 07039 } 07040 07041 if (!finish_sm_op(bodies, new_sms, new_bodies)) 07042 result = CUBIT_FAILURE; 07043 07044 if( CubitUndo::get_undo_enabled() ) 07045 { 07046 if( new_bodies.size() ) 07047 CubitUndo::note_result_bodies( new_bodies ); 07048 else 07049 CubitUndo::remove_last_undo(); 07050 } 07051 07052 // Update graphics 07053 while (entities_to_update.size()) 07054 { 07055 RefEntity* entity = entities_to_update.pop(); 07056 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, entity)); 07057 } 07058 07059 return result; 07060 } 07061 07062 07063 CubitStatus GeometryModifyTool::validate_normals(DLIList<Body*>& bodies, 07064 RefFace *surf_ref, 07065 bool reverse) 07066 { 07067 if (bodies.size() <= 0) 07068 { 07069 PRINT_WARNING("There are no entities in the list. Nothing modified\n"); 07070 return CUBIT_FAILURE; 07071 } 07072 07073 DLIList<RefEntity*> temp; 07074 CAST_LIST_TO_PARENT(bodies, temp); 07075 if ( !same_modify_engine(temp, CUBIT_TRUE)) 07076 { 07077 PRINT_ERROR("Performing VALIDATE NORMALS with volumes containing geometry\n" 07078 " from different modeling engines is not allowed. Delete uncommon\n" 07079 " geometry on these volumes before operation.\n\n"); 07080 return CUBIT_FAILURE; 07081 } 07082 07083 // Get the GeometryEngine for each Body of the list to check 07084 // if they are the same and if they are GeometryModifyEngine 07085 GeometryModifyEngine* gePtr1 = get_engine(bodies.get()); 07086 GeometryModifyEngine* gePtr2; 07087 Body* Body_ptr = NULL; 07088 bodies.reset(); 07089 for( int i = bodies.size(); i > 0; i--) 07090 { 07091 Body_ptr = bodies.get_and_step(); 07092 gePtr2 = get_engine(Body_ptr); 07093 if (gePtr1 != gePtr2) 07094 { 07095 PRINT_ERROR("In GeometryModifyTool::validate_normals\n" 07096 " Volumes are associated with different GMEs. \n"); 07097 return CUBIT_FAILURE; 07098 } 07099 if ( gePtr2 == NULL) 07100 { 07101 PRINT_ERROR("In GeometryModifyTool::validate_normals\n" 07102 " Body %d is not associated with a SME.\n", 07103 Body_ptr->id()); 07104 return CUBIT_FAILURE; 07105 } 07106 } 07107 07108 07109 DLIList<RefFace*> ref_face_list; 07110 DLIList<RefFace*> free_face_list; 07111 DLIList<RefFace*> bad_face_list; 07112 07113 //gather all the faces from all the bodies 07114 bodies.reset(); 07115 for( int i=bodies.size(); i--; ) 07116 { 07117 Body* BodyPtr = bodies.get_and_step(); 07118 BodyPtr->ref_faces(free_face_list); 07119 } 07120 07121 RefFace *ref_face_ptr; 07122 RefFace *inter_face_ptr; 07123 07124 if(surf_ref != NULL) // getting the starting surface 07125 { 07126 ref_face_ptr = surf_ref; 07127 } 07128 else 07129 { 07130 ref_face_ptr = free_face_list.get_and_step(); 07131 } 07132 07133 ref_face_list.append(ref_face_ptr); 07134 free_face_list.remove(ref_face_ptr); 07135 free_face_list.reset(); 07136 07137 while(free_face_list.size()) 07138 { 07139 DLIList<RefEdge*> curve_list; 07140 ref_face_ptr->ref_edges(curve_list); 07141 free_face_list.reset(); 07142 for(int jj=free_face_list.size(); jj > 0; jj--) // getting a new searching surface 07143 { 07144 inter_face_ptr = free_face_list.get_and_step(); 07145 DLIList<RefEdge*> inter_curve_list; 07146 inter_face_ptr->ref_edges(inter_curve_list); 07147 curve_list.reset(); 07148 // PRINT_INFO("base face %d working on face %d\n", ref_face_ptr->id(),inter_face_ptr->id()); 07149 07150 for (int k= curve_list.size(); k > 0; k--) // looping through all of the surface curves 07151 { 07152 RefEdge *ref_check_curve = curve_list.step_and_get(); 07153 inter_curve_list.reset(); 07154 07155 for (int kk = inter_curve_list.size(); kk > 0; kk--) 07156 { 07157 RefEdge *check_curve = inter_curve_list.step_and_get(); 07158 07159 if(ref_check_curve == check_curve) // finding if a surface is connected 07160 { 07161 DLIList<CoEdge*> coedge_list; 07162 check_curve->co_edges(coedge_list); 07163 07164 CoEdge* first_coedge = coedge_list.get_and_step(); 07165 CoEdge* second_coedge = coedge_list.get_and_step(); 07166 07167 if((first_coedge->get_sense() == second_coedge->get_sense() && 07168 !bad_face_list.is_in_list(ref_face_ptr) ) || 07169 (first_coedge->get_sense() != second_coedge->get_sense() && 07170 bad_face_list.is_in_list(ref_face_ptr) )) // finding if a surface has a fliped normal 07171 { 07172 bad_face_list.append(inter_face_ptr); 07173 PRINT_INFO("Surface %d is not consistent\n", inter_face_ptr->id()); 07174 } 07175 07176 ref_face_list.append(inter_face_ptr); // adding to the searched list 07177 free_face_list.remove(inter_face_ptr); // removing from the unsearched list 07178 } 07179 07180 } 07181 07182 } 07183 07184 } 07185 07186 ref_face_list.remove(ref_face_ptr); // removeing from the searched list 07187 ref_face_list.last(); 07188 if(ref_face_list.size() <= 0) 07189 { 07190 PRINT_ERROR("In GeometryModifyTool::validate_normals\n" 07191 " all surfaces must be connected\n"); 07192 return CUBIT_FAILURE; 07193 } 07194 ref_face_ptr = ref_face_list.get(); 07195 } 07196 07197 if (reverse && bad_face_list.size()) 07198 { 07199 //CubitStatus result = gePtr1->flip_normals(bad_face_list); 07200 CubitStatus result = GeometryModifyTool::instance()->reverse(bad_face_list); 07201 if ( result == CUBIT_FAILURE ) 07202 { 07203 return CUBIT_FAILURE; 07204 } 07205 } 07206 else if(!bad_face_list.size()) 07207 { 07208 PRINT_INFO("All surfaces are consistent\n"); 07209 } 07210 return CUBIT_SUCCESS; 07211 } 07212 07213 07214 07215 CubitStatus GeometryModifyTool::subtract( Body* tool_body, DLIList<Body*> &from_bodies, 07216 DLIList<Body*> &new_bodies, 07217 bool imprint, 07218 bool keep_old ) 07219 { 07220 DLIList<Body*> temp_body_list; 07221 temp_body_list.append(tool_body); 07222 return subtract(temp_body_list, from_bodies, new_bodies, imprint, keep_old); 07223 } 07224 07225 07226 CubitStatus GeometryModifyTool::subtract( DLIList<Body*> &tool_body_list, 07227 DLIList<Body*> &from_bodies, 07228 DLIList<Body*> &new_bodies, 07229 bool imprint, 07230 bool keep_old ) 07231 { 07232 if(tool_body_list.size() == 0 ) 07233 return CUBIT_FAILURE; 07234 if(from_bodies.size() == 0 ) 07235 return CUBIT_FAILURE; 07236 DLIList<Body*> tem_bodies(tool_body_list); 07237 07238 // cannot subtract from self 07239 int old_size = from_bodies.size(); 07240 from_bodies -= tool_body_list; 07241 if (from_bodies.size() != old_size) 07242 { 07243 PRINT_WARNING("Cannot subtract body from itself. Ignoring \"from\" body.\n"); 07244 if (!from_bodies.size()) 07245 return CUBIT_FAILURE; 07246 } 07247 07248 tem_bodies += from_bodies; 07249 if (!okay_to_modify( tem_bodies, "SUBTRACT" )) 07250 return CUBIT_FAILURE; 07251 07252 DLIList<BodySM*> tool_sms(tool_body_list.size()); 07253 DLIList<BodySM*> from_sms(from_bodies.size()); 07254 GeometryModifyEngine* gme = common_modify_engine( tool_body_list, tool_sms ); 07255 GeometryModifyEngine* gme2 = common_modify_engine( from_bodies, from_sms ); 07256 if (!gme || gme != gme2) 07257 { 07258 PRINT_ERROR("Performing SUBTRACTION with volumes containing geometry\n" 07259 "from different modeling engines is not allowed.\n" 07260 "Delete uncommon geometry on these volumes before operation.\n\n"); 07261 return CUBIT_FAILURE; 07262 } 07263 07264 if( CubitUndo::get_undo_enabled() ) 07265 { 07266 if( keep_old ) 07267 CubitUndo::save_state(); 07268 else 07269 { 07270 //Get all the bodies associated with the vertex 07271 DLIList<Body*> bodies; 07272 bodies += tool_body_list; 07273 bodies += from_bodies; 07274 CubitUndo::save_state_with_cubit_file( bodies ); 07275 } 07276 } 07277 07278 DLIList<int> merged_surface_ids; 07279 DLIList<int> merged_curve_ids; 07280 if( keep_old == CUBIT_FALSE ) 07281 get_merged_curve_and_surface_ids( from_bodies, merged_surface_ids, merged_curve_ids ); 07282 07283 07284 // Do the subtract operation 07285 DLIList<BodySM*> new_sms; 07286 CubitStatus result = gme->subtract(tool_sms, from_sms, new_sms, imprint, keep_old ); 07287 07288 if( CubitUndo::get_undo_enabled() && result == CUBIT_FAILURE ) 07289 CubitUndo::remove_last_undo(); 07290 07291 CubitStatus result2 = finish_sm_op(tem_bodies, new_sms, new_bodies); 07292 07293 if( CubitUndo::get_undo_enabled() ) 07294 { 07295 if( result == CUBIT_SUCCESS ) 07296 CubitUndo::note_result_bodies( new_bodies ); 07297 else 07298 CubitUndo::remove_last_undo(); 07299 } 07300 07301 if ( result == CUBIT_FAILURE || result2 == CUBIT_FAILURE) 07302 { 07303 PRINT_ERROR("Subtract FAILED\n" ); 07304 return CUBIT_FAILURE; 07305 } 07306 07307 if( keep_old == CUBIT_FALSE ) 07308 fixup_merged_entities( merged_surface_ids, merged_curve_ids); 07309 07310 return CUBIT_SUCCESS; 07311 } 07312 07313 CubitStatus GeometryModifyTool::intersect( DLIList<Body*> &from_bodies, 07314 DLIList<Body*> &new_bodies, 07315 bool keep_old, 07316 bool preview) 07317 { 07318 DLIList<Body*> tem_bodies = from_bodies; 07319 if (!okay_to_modify( tem_bodies, "INTERSECT" )) 07320 return CUBIT_FAILURE; 07321 07322 GfxPreview::clear(); 07323 07324 DLIList<BodySM*> from_sm_list(tem_bodies.size()); 07325 GeometryModifyEngine* engine = common_modify_engine(tem_bodies, from_sm_list); 07326 if ( NULL == engine ) 07327 { 07328 PRINT_ERROR("Performing INTERSECTION with volumes containing geometry\n" 07329 "from different modeling engines is not allowed.\n" 07330 "Delete uncommon geometry on these volumes before operation.\n\n"); 07331 return CUBIT_FAILURE; 07332 } 07333 07334 if( !preview && CubitUndo::get_undo_enabled() ) 07335 { 07336 if( keep_old ) 07337 CubitUndo::save_state(); 07338 else 07339 CubitUndo::save_state_with_cubit_file( from_bodies ); 07340 } 07341 07342 DLIList<int> merged_surface_ids; 07343 DLIList<int> merged_curve_ids; 07344 if( !preview && (keep_old == CUBIT_FALSE) ) 07345 get_merged_curve_and_surface_ids( from_bodies, merged_surface_ids, merged_curve_ids ); 07346 07347 GeometryModifyEngine* gme_ptr = get_engine(from_sm_list.get()); 07348 GeometryQueryEngine* gqe_ptr = gme_ptr->get_gqe(); 07349 07350 DLIList<BodySM*> all_new_bodysms; 07351 int i,j; 07352 for( i=0; i<from_sm_list.size(); i++ ) 07353 { 07354 from_sm_list.reset(); 07355 from_sm_list.step(i); 07356 BodySM *body1 = from_sm_list.get_and_step(); 07357 07358 for(j=i+1; j<from_sm_list.size(); j++ ) 07359 { 07360 BodySM *body2 = from_sm_list.get_and_step(); 07361 07362 if( body1 == body2 ) 07363 continue; 07364 07365 //copy the bodies 07366 BodySM *body1_copy = gme_ptr->copy_body( body1 ); 07367 BodySM *body2_copy = gme_ptr->copy_body( body2 ); 07368 07369 DLIList<BodySM*> tmp_sm_list(1); 07370 tmp_sm_list.append( body2_copy ); 07371 DLIList<BodySM*> new_sms; 07372 07373 CubitStatus result = 07374 engine->intersect(body1_copy, tmp_sm_list, new_sms, true, preview ); 07375 07376 //delete the copies 07377 gqe_ptr->delete_solid_model_entities( body1_copy ); 07378 gqe_ptr->delete_solid_model_entities( body2_copy ); 07379 07380 if (!preview) 07381 { 07382 if ( result == CUBIT_FAILURE || new_sms.size() == 0 ) 07383 { 07384 RefEntity* ref_ent1 = dynamic_cast<RefEntity*>(body1->topology_entity()); 07385 RefEntity* ref_ent2 = dynamic_cast<RefEntity*>(body2->topology_entity()); 07386 07387 PRINT_WARNING("INTERSECTION of %s with %s failed\n", 07388 ref_ent1->entity_name().c_str(), 07389 ref_ent2->entity_name().c_str() ); 07390 continue; 07391 07392 } 07393 07394 all_new_bodysms += new_sms; 07395 } 07396 } 07397 } 07398 07399 if (!preview) 07400 { 07401 //now make all the RefEntities 07402 all_new_bodysms.reset(); 07403 for( i=all_new_bodysms.size(); i--; ) 07404 { 07405 Body *new_body = GeometryQueryTool::instance()->make_Body(all_new_bodysms.get_and_step()); 07406 if( new_body ) 07407 new_bodies.append( new_body ); 07408 } 07409 07410 if( CubitUndo::get_undo_enabled() ) 07411 { 07412 if( all_new_bodysms.size() ) 07413 CubitUndo::note_result_bodies( new_bodies ); 07414 else 07415 CubitUndo::remove_last_undo(); 07416 } 07417 07418 if( keep_old == CUBIT_FALSE ) 07419 fixup_merged_entities( merged_surface_ids, merged_curve_ids); 07420 } 07421 07422 return CUBIT_SUCCESS; 07423 } 07424 07425 07426 07427 CubitStatus GeometryModifyTool::intersect( Body *tool_body_ptr, 07428 DLIList<Body*> &from_bodies, 07429 DLIList<Body*> &new_bodies, 07430 bool keep_old, 07431 bool preview) 07432 { 07433 if(tool_body_ptr == NULL ) 07434 return CUBIT_FAILURE; 07435 if(from_bodies.size() == 0 || from_bodies.get() == NULL ) 07436 return CUBIT_FAILURE; 07437 07438 GfxPreview::clear(); 07439 07440 DLIList<Body*> tem_bodies = from_bodies; 07441 tem_bodies.append( tool_body_ptr ); 07442 if (!okay_to_modify( tem_bodies, "INTERSECT" )) 07443 return CUBIT_FAILURE; 07444 07445 DLIList<BodySM*> from_sm_list(tem_bodies.size()); 07446 GeometryModifyEngine* engine = common_modify_engine(tem_bodies, from_sm_list); 07447 if ( NULL == engine ) 07448 { 07449 PRINT_ERROR("Performing INTERSECTION with volumes containing geometry\n" 07450 "from different modeling engines is not allowed.\n" 07451 "Delete uncommon geometry on these volumes before operation.\n\n"); 07452 return CUBIT_FAILURE; 07453 } 07454 07455 BodySM* tool_sm = from_sm_list.pop(); 07456 07457 07458 //cannot intersect tool with itself 07459 from_sm_list.remove_all_with_value( tool_sm ); 07460 if( from_sm_list.size() == 0 ) 07461 { 07462 PRINT_ERROR("Cannot intersect volume %d from itself\n", 07463 tool_body_ptr->ref_volume()->id() ); 07464 return CUBIT_FAILURE; 07465 } 07466 07467 if( !preview && CubitUndo::get_undo_enabled() ) 07468 { 07469 if( keep_old ) 07470 CubitUndo::save_state(); 07471 else 07472 { 07473 DLIList<Body*> bodies; 07474 bodies.append( tool_body_ptr ); 07475 bodies += from_bodies; 07476 CubitUndo::save_state_with_cubit_file( bodies ); 07477 } 07478 } 07479 07480 DLIList<int> merged_surface_ids; 07481 DLIList<int> merged_curve_ids; 07482 if( !preview && (keep_old == CUBIT_FALSE) ) 07483 get_merged_curve_and_surface_ids( from_bodies, merged_surface_ids, merged_curve_ids ); 07484 07485 // Do the intersect operation 07486 DLIList<BodySM*> new_sms; 07487 CubitStatus result = 07488 engine->intersect(tool_sm, from_sm_list, new_sms, keep_old, preview ); 07489 07490 if (!preview) 07491 { 07492 result = finish_sm_op(tem_bodies, new_sms, new_bodies); 07493 07494 if( CubitUndo::get_undo_enabled() ) 07495 { 07496 if( result == CUBIT_SUCCESS ) 07497 CubitUndo::note_result_bodies( new_bodies ); 07498 else 07499 CubitUndo::remove_last_undo(); 07500 } 07501 07502 if ( result == CUBIT_FAILURE ) 07503 { 07504 PRINT_ERROR("Intersect FAILED\n" ); 07505 return CUBIT_FAILURE; 07506 } 07507 07508 if( keep_old == CUBIT_FALSE ) 07509 fixup_merged_entities( merged_surface_ids, merged_curve_ids); 07510 } 07511 07512 return CUBIT_SUCCESS; 07513 } 07514 07515 CubitStatus GeometryModifyTool::imprint( DLIList<Body*> &from_body_list, 07516 DLIList<Body*> &new_body_list, 07517 CubitBoolean keep_old ) 07518 { 07519 if( from_body_list.size() == 1 ) 07520 { 07521 PRINT_WARNING("Need more than 1 body or volume to imprint.\n"); 07522 return CUBIT_FAILURE; 07523 } 07524 07525 if (get_group_imprint() == CUBIT_FALSE) 07526 { 07527 CubitStatus result = imprint_singly( from_body_list, new_body_list, keep_old ); 07528 return result; 07529 } 07530 07531 // Check the GeometryEngine for each of the Body's; check to 07532 // make sure they're all the same 07533 from_body_list.reset(); 07534 if (!okay_to_modify( from_body_list, "IMPRINT" )) 07535 return CUBIT_FAILURE; 07536 07537 //Check for repeats in each individual list and for overlap 07538 //between the two lists. 07539 from_body_list.uniquify_ordered(); 07540 07541 DLIList<BodySM*> from_sms(from_body_list.size()), new_sms; 07542 GeometryModifyEngine* gePtr1 = common_modify_engine(from_body_list, from_sms); 07543 if ( !gePtr1 ) 07544 { 07545 PRINT_ERROR("Performing IMPRINT with volumes containing geometry\n" 07546 "from different modeling engines is not allowed.\n" 07547 "Delete uncommon geometry on these volumes before operation.\n\n"); 07548 return CUBIT_FAILURE; 07549 } 07550 07551 if( CubitUndo::get_undo_enabled() ) 07552 { 07553 if( keep_old ) 07554 CubitUndo::save_state(); 07555 else 07556 CubitUndo::save_state_with_cubit_file( from_body_list ); 07557 } 07558 07559 int process_composites = 0; 07560 if(contains_composites(from_body_list)) 07561 process_composites = 1; 07562 07563 if(process_composites) 07564 { 07565 // Push virtual attributes down to solid model topology before 07566 // doing the imprint. 07567 do_attribute_setup(); 07568 push_attributes_before_modify(from_sms); 07569 // This must be done after pushing the vg atts because it uses them. 07570 DLIList<TopologyBridge*> tb_list; 07571 CAST_LIST(from_sms, tb_list, TopologyBridge); 07572 push_named_attributes_to_curves_and_points(tb_list, "IMPRINTER"); 07573 push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL"); 07574 } 07575 07576 CubitStatus result = gePtr1->imprint(from_sms, new_sms, keep_old); 07577 07578 int i, j; 07579 if(process_composites) 07580 { 07581 if(result == CUBIT_SUCCESS) 07582 { 07583 // Analyze the results and adjust virtual attributes as necessary. 07584 DLIList<TopologyBridge*> tb_list; 07585 CAST_LIST(new_sms, tb_list, TopologyBridge); 07586 GeometryQueryTool::instance()->ige_attribute_after_imprinting(tb_list, from_body_list); 07587 07588 // Clean up attributes. 07589 remove_imprint_attributes_after_modify(from_sms, new_sms); 07590 07591 // Restore the virtual geometry. 07592 restore_vg_after_modify(new_sms, from_body_list, gePtr1); 07593 } 07594 remove_pushed_attributes(new_sms, from_body_list); 07595 } 07596 07597 if (get_old_names() == CUBIT_FALSE) 07598 { 07599 if (!finish_sm_op(from_body_list, new_sms, new_body_list)) 07600 result = CUBIT_FAILURE; 07601 07602 if( CubitUndo::get_undo_enabled() ) 07603 { 07604 if( result == CUBIT_SUCCESS ) 07605 CubitUndo::note_result_bodies( new_body_list ); 07606 else 07607 CubitUndo::remove_last_undo(); 07608 } 07609 07610 if(process_composites) 07611 do_attribute_cleanup(); 07612 07613 return result; 07614 } 07615 07616 if(process_composites) 07617 do_attribute_cleanup(); 07618 07619 // If old_names is true, need to make sure things are deleted in 07620 // the correct order so that entities get the same @A type extension 07621 // on their names. 07622 07623 // Update existing bodies. 07624 from_body_list.reset(); 07625 for (i = from_body_list.size(); i--; ) 07626 { 07627 Body* body = from_body_list.get(); 07628 BodySM* body_sm = body->get_body_sm_ptr(); 07629 if (!body_sm) 07630 { 07631 GeometryQueryTool::instance()->destroy_dead_entity(body); 07632 from_body_list.change_to(0); 07633 } 07634 else 07635 { 07636 remove_dead_entity_names(body); 07637 GeometryQueryTool::instance()->make_Body(body_sm); 07638 } 07639 from_body_list.step(); 07640 } 07641 07642 // Construct new bodies 07643 new_sms.reset(); 07644 for (j = new_sms.size(); j--; ) 07645 { 07646 BodySM* body_sm = new_sms.get_and_step(); 07647 Body* body = GeometryQueryTool::instance()->make_Body(body_sm); 07648 new_body_list.append(body); 07649 } 07650 GeometryQueryTool::instance()->cleanout_deactivated_geometry(); 07651 07652 if( CubitUndo::get_undo_enabled() ) 07653 { 07654 if( result == CUBIT_SUCCESS ) 07655 CubitUndo::note_result_bodies( new_body_list ); 07656 else 07657 CubitUndo::remove_last_undo(); 07658 } 07659 07660 return result; 07661 } 07662 07663 CubitStatus GeometryModifyTool::scale( Body *&body, 07664 const CubitVector& point, 07665 const CubitVector& factors, 07666 bool check_to_transform, 07667 bool preview /*=false*/, 07668 bool reset_preview /*true*/) 07669 { 07670 if( check_to_transform ) 07671 if (!GeometryQueryTool::instance()->okay_to_transform( body )) 07672 return CUBIT_FAILURE; 07673 07674 DLIList<Body*> body_list; 07675 body_list.append(body); 07676 if (!okay_to_modify( body_list, "NON_UNIFORM_SCALE" )) 07677 return CUBIT_FAILURE; 07678 07679 if(reset_preview) 07680 GfxPreview::clear(); 07681 07682 if (preview) 07683 { 07684 DLIList<RefEdge*> edges; 07685 body->ref_edges(edges); 07686 07687 //set up the matrices 07688 CubitTransformMatrix pre_mat, scale_mat, post_mat; 07689 pre_mat.translate(-point); 07690 scale_mat.scale_about_origin(factors); 07691 post_mat.translate(point); 07692 07693 for (int i = 0; i < edges.size(); i++) 07694 { 07695 GMem poly; 07696 07697 if( CUBIT_SUCCESS == edges[i]->get_graphics(poly) ) 07698 { 07699 poly.transform(pre_mat); 07700 poly.transform(scale_mat); 07701 poly.transform(post_mat); 07702 GfxPreview::draw_polyline(poly.point_list(), poly.point_list_size(), CUBIT_BLUE_INDEX); 07703 } 07704 else if( edges[i]->start_vertex() == edges[i]->end_vertex() ) 07705 { 07706 CubitVector tmp_pt = edges[i]->start_vertex()->coordinates(); 07707 tmp_pt = pre_mat*tmp_pt; 07708 tmp_pt = scale_mat*tmp_pt; 07709 tmp_pt = post_mat*tmp_pt; 07710 GfxPreview::draw_point( tmp_pt, CUBIT_BLUE_INDEX); 07711 } 07712 } 07713 GfxPreview::flush(); 07714 return CUBIT_SUCCESS; 07715 } 07716 07717 do_attribute_setup(); 07718 07719 BodySM* bodysm = body->get_body_sm_ptr(); 07720 DLIList<BodySM*> body_sm_list; 07721 body_sm_list.append(bodysm); 07722 07723 push_attributes_before_modify(body_sm_list); 07724 07725 GeometryModifyEngine* engine = get_engine( bodysm ); 07726 CubitStatus result; 07727 if( !engine ) 07728 { 07729 GeometryQueryEngine* tmp_engine = bodysm->get_geometry_query_engine(); 07730 result = tmp_engine->translate( bodysm, -point ); 07731 result = tmp_engine->scale( bodysm, factors ); 07732 result = tmp_engine->translate( bodysm, point ); 07733 07734 } 07735 else 07736 { 07737 GeometryQueryEngine* tmp_engine = bodysm->get_geometry_query_engine(); 07738 result = tmp_engine->translate( bodysm, -point ); 07739 result = engine->scale( bodysm, factors ); 07740 result = tmp_engine->translate( bodysm, point ); 07741 } 07742 07743 // The bodysm pointer may get changed depending on the underlying 07744 // engine. Make sure to put the most current pointer in the list 07745 // for further processing. 07746 body_sm_list.clean_out(); 07747 body_sm_list.append(bodysm); 07748 // The old body will probably have stale data at this point 07749 // so don't send it down for further processing. 07750 body_list.clean_out(); 07751 07752 restore_vg_after_modify( body_sm_list, body_list, engine ); 07753 remove_pushed_attributes( body_sm_list, body_list ); 07754 07755 //for non-uniform scaling, topology can change...need to update stuff 07756 if( factors.x() != factors.y() || 07757 factors.y() != factors.z() || 07758 factors.z() != factors.x() ) 07759 body = GeometryQueryTool::instance()->make_Body(bodysm); 07760 07761 do_attribute_cleanup(); 07762 07763 if (result) 07764 { 07765 07766 CubitTransformMatrix pre_mat; 07767 pre_mat.translate(-point); 07768 07769 CubitTransformMatrix scale_mat; 07770 scale_mat.scale_about_origin(factors); 07771 07772 CubitTransformMatrix post_mat; 07773 post_mat.translate(point); 07774 GeometryQueryTool::instance()->notify_intermediate_of_transform( body, pre_mat ); 07775 GeometryQueryTool::instance()->notify_intermediate_of_transform( body, scale_mat ); 07776 GeometryQueryTool::instance()->notify_intermediate_of_transform( body, post_mat ); 07777 GeometryQueryTool::instance()->notify_observers_of_transform( body ); 07778 } 07779 else 07780 PRINT_ERROR("Scale of %s (%s %d) failed.\n", 07781 body->entity_name().c_str(), body->class_name(), body->id() ); 07782 07783 return result; 07784 } 07785 07786 07787 07788 CubitStatus GeometryModifyTool::imprint_singly( DLIList<Body*> &from_body_list, 07789 DLIList<Body*> &new_body_list, 07790 CubitBoolean keep_old ) 07791 { 07792 07793 // Check the GeometryEngine for each of the Body's; check to 07794 // make sure they're all the same 07795 from_body_list.reset(); 07796 if (!okay_to_modify( from_body_list, "IMPRINT" )) 07797 return CUBIT_FAILURE; 07798 07799 //Check for repeats in each individual list and for overlap 07800 //between the two lists. 07801 from_body_list.uniquify_ordered(); 07802 07803 DLIList<BodySM*> from_sms(from_body_list.size()); 07804 GeometryModifyEngine* gePtr1 = common_modify_engine(from_body_list, from_sms); 07805 if ( !gePtr1 ) 07806 { 07807 PRINT_ERROR("Performing IMPRINT with volumes containing geometry\n" 07808 "from different modeling engines is not allowed.\n" 07809 "Delete uncommon geometry on these volumes before operation.\n\n"); 07810 return CUBIT_FAILURE; 07811 } 07812 07813 CubitBoolean reset_new_ids = CUBIT_FALSE; 07814 if (get_new_ids() == CUBIT_FALSE) { 07815 PRINT_WARNING("New ids must be TRUE when group imprint FALSE; " 07816 "setting new ids TRUE for this operation only.\n"); 07817 set_new_ids(CUBIT_TRUE); 07818 reset_new_ids = CUBIT_TRUE; 07819 } 07820 07821 // do the imprinting; bounding box should be checked in 07822 // SMEEngine function 07823 new_body_list = from_body_list; 07824 GeometryQueryTool* gqt = GeometryQueryTool::instance(); 07825 07826 if( CubitUndo::get_undo_enabled() ) 07827 { 07828 if( keep_old ) 07829 CubitUndo::save_state(); 07830 else 07831 CubitUndo::save_state_with_cubit_file( from_body_list ); 07832 } 07833 07834 int i; 07835 for (i = 0; i < new_body_list.size(); i++) { 07836 for (int j = 1; j < new_body_list.size()-i; j++) { 07837 new_body_list.reset(); 07838 new_body_list.step(i); 07839 Body *body_1 = new_body_list.get(); 07840 Body *body_2 = new_body_list.next(j); 07841 Body *newBodyPtr1 = NULL; 07842 Body *newBodyPtr2 = NULL; 07843 07844 if (body_1 == body_2) { 07845 PRINT_WARNING("Can't imprint a volume with itself.\n"); 07846 07847 if (reset_new_ids == CUBIT_TRUE) set_new_ids(CUBIT_FALSE); 07848 07849 return CUBIT_FAILURE; 07850 } 07851 07852 BodySM *new_sm_1, *new_sm_2; 07853 CubitStatus status = gePtr1->imprint(body_1->get_body_sm_ptr(), 07854 body_2->get_body_sm_ptr(), 07855 new_sm_1, new_sm_2, 07856 keep_old); 07857 07858 if ( status != CUBIT_FAILURE && 07859 (new_sm_1 != NULL || 07860 new_sm_2 != NULL) ) 07861 { 07862 from_body_list.reset(); 07863 from_body_list.step(i); 07864 07865 //put the new ones in the new list and 07866 //remove the olds ones. 07867 if ( new_sm_1 != NULL ) 07868 { 07869 if (!body_1->get_body_sm_ptr()) 07870 gqt->destroy_dead_entity(body_1); 07871 newBodyPtr1 = gqt->make_Body(new_sm_1); 07872 new_body_list.change_to(newBodyPtr1); 07873 from_body_list.change_to(0); 07874 } 07875 else 07876 gqt->make_Body(body_1->get_body_sm_ptr()); 07877 07878 new_body_list.step(j); 07879 from_body_list.step(j); 07880 if ( new_sm_2 != NULL ) 07881 { 07882 if (!body_2->get_body_sm_ptr()) 07883 gqt->destroy_dead_entity(body_2); 07884 newBodyPtr2 = gqt->make_Body(new_sm_2); 07885 new_body_list.change_to(newBodyPtr2); 07886 from_body_list.change_to(NULL); 07887 } 07888 else 07889 gqt->make_Body(body_2->get_body_sm_ptr()); 07890 } 07891 gqt->cleanout_deactivated_geometry(); 07892 } 07893 } 07894 07895 from_body_list.remove_all_with_value(NULL); 07896 Body *temp_body; 07897 for (i = from_body_list.size(); i > 0; i--) 07898 { 07899 temp_body = from_body_list.get_and_step(); 07900 while (new_body_list.move_to(temp_body)) new_body_list.remove(); 07901 } 07902 07903 if( CubitUndo::get_undo_enabled() ) 07904 { 07905 if( new_body_list.size() ) 07906 CubitUndo::note_result_bodies( new_body_list ); 07907 else 07908 CubitUndo::remove_last_undo(); 07909 } 07910 07911 PRINT_INFO("\n"); 07912 if( DEBUG_FLAG( 153 ) ) 07913 { 07914 PRINT_INFO( " New Body(ies) created:"); 07915 new_body_list.reset(); 07916 for (i = 0; i < new_body_list.size(); i++) 07917 { 07918 if (i != 0) PRINT_INFO( ","); 07919 PRINT_INFO( " %d", new_body_list.get_and_step()->id()); 07920 } 07921 PRINT_INFO("\n"); 07922 PRINT_INFO( " Original Body(ies) retained:"); 07923 from_body_list.reset(); 07924 for (i = 0; i < from_body_list.size(); i++) 07925 { 07926 if (i != 0) PRINT_INFO( ","); 07927 PRINT_INFO( " %d", from_body_list.get_and_step()->id()); 07928 } 07929 PRINT_INFO("\n"); 07930 } 07931 07932 PRINT_INFO( " New Volume(s) created:"); 07933 new_body_list.reset(); 07934 DLIList<RefVolume*> new_vol_list; 07935 for (i = 0; i < new_body_list.size(); i++) 07936 { 07937 DLIList<RefVolume*> t2; 07938 new_body_list.get_and_step()->ref_volumes( t2 ); 07939 new_vol_list += t2; 07940 } 07941 07942 for( i = 0; i < new_vol_list.size(); i++ ) 07943 { 07944 if (i != 0) PRINT_INFO( ","); 07945 PRINT_INFO( " %d", new_vol_list.get_and_step()->id()); 07946 } 07947 PRINT_INFO("\n"); 07948 07949 PRINT_INFO( " Original Volume(s) retained:"); 07950 from_body_list.reset(); 07951 DLIList<RefVolume*> from_vol_list; 07952 for (i = 0; i < from_body_list.size(); i++) 07953 { 07954 DLIList<RefVolume*> t2; 07955 from_body_list.get_and_step()->ref_volumes( t2 ); 07956 from_vol_list += t2; 07957 } 07958 07959 for( i = 0; i < from_vol_list.size(); i++ ) 07960 { 07961 if (i != 0) PRINT_INFO( ","); 07962 PRINT_INFO( " %d", from_vol_list.get_and_step()->id()); 07963 } 07964 PRINT_INFO("\n"); 07965 07966 if (reset_new_ids) set_new_ids(CUBIT_FALSE); 07967 07968 return CUBIT_SUCCESS; 07969 } 07970 07971 07972 CubitStatus GeometryModifyTool::imprint( DLIList<Body*> &body_list, 07973 DLIList<RefEdge*> &ref_edge_list, 07974 DLIList<Body*>& new_body_list, 07975 CubitBoolean keep_old_body, 07976 CubitBoolean show_messages) 07977 { 07978 // Check the GeometryEngine for each of the bodies; check to 07979 // make sure they're all the same 07980 body_list.reset(); 07981 int i; 07982 07983 if (!okay_to_modify( body_list, "IMPRINT" )) 07984 return CUBIT_FAILURE; 07985 07986 const int count = body_list.size() + ref_edge_list.size(); 07987 DLIList<TopologyEntity*> entity_list(count); 07988 DLIList<TopologyBridge*> bridge_list(count); 07989 CAST_LIST_TO_PARENT(body_list, entity_list); 07990 ref_edge_list.reset(); 07991 for (i = ref_edge_list.size(); i--;) 07992 entity_list.append(ref_edge_list.get_and_step()); 07993 07994 GeometryModifyEngine* gePtr1 = common_modify_engine(entity_list, bridge_list); 07995 07996 DLIList<BodySM*> body_sm_list(body_list.size()); 07997 DLIList<Curve*> curve_list(ref_edge_list.size()); 07998 CAST_LIST(bridge_list, body_sm_list, BodySM); 07999 CAST_LIST(bridge_list, curve_list, Curve); 08000 08001 if ( !gePtr1 || 08002 body_sm_list.size() != body_list.size() || 08003 curve_list.size() != ref_edge_list.size() ) 08004 { 08005 PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n" 08006 "different modeling engines is not allowed.\n" 08007 "Delete uncommon geometry on these volumes before operation.\n\n"); 08008 return CUBIT_FAILURE; 08009 } 08010 08011 if( CubitUndo::get_undo_enabled() ) 08012 { 08013 if( keep_old_body ) 08014 CubitUndo::save_state(); 08015 else 08016 CubitUndo::save_state_with_cubit_file( body_list ); 08017 } 08018 08019 int process_composites = 0; 08020 if(contains_composites(body_list)) 08021 process_composites = 1; 08022 08023 if(process_composites) 08024 { 08025 // Turn certain attributes on. 08026 do_attribute_setup(); 08027 // Push virtual attributes down to solid model topology before 08028 // doing the imprint. 08029 push_attributes_before_modify(body_sm_list); 08030 // Put "ORIGINAL" attributes on the bodies being imprinted and 08031 // the curves as these originally existed. 08032 DLIList<TopologyBridge*> tb_list; 08033 CAST_LIST(body_sm_list, tb_list, TopologyBridge); 08034 push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL"); 08035 tb_list.clean_out(); 08036 CAST_LIST(curve_list, tb_list, TopologyBridge); 08037 push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL"); 08038 } 08039 08040 DLIList<BodySM*> new_sm_list; 08041 // The bridges doing the imprinting often get split during the process but 08042 // because of the way we are making copies, the IMPRINTER attribute doesn't 08043 // get propagated to them. temporary_bridges will be filled in with any 08044 // additional IMPRINTER bridges we need to consider below when deciding whether to 08045 // keep composite attributes. 08046 DLIList<TopologyBridge*> temporary_bridges; 08047 CubitStatus status = gePtr1->imprint( body_sm_list, curve_list, 08048 new_sm_list, temporary_bridges, keep_old_body, show_messages); 08049 08050 temporary_bridges.uniquify_ordered(); 08051 08052 if(status == CUBIT_FAILURE) 08053 { 08054 if(process_composites) 08055 { 08056 remove_pushed_attributes(new_sm_list, body_list); 08057 do_attribute_cleanup(); 08058 } 08059 08060 while(temporary_bridges.size()) 08061 { 08062 TopologyBridge* bridge = temporary_bridges.pop(); 08063 bridge->get_geometry_query_engine()->delete_topology_bridge(bridge); 08064 } 08065 08066 return status; 08067 } 08068 else 08069 { 08070 if(process_composites) 08071 { 08072 DLIList<TopologyBridge*> tb_list; 08073 // Analyze the results and adjust virtual attributes as necessary. 08074 CAST_LIST(new_sm_list, tb_list, TopologyBridge); 08075 // The bridges coming back in temporary_bridges may not have IMPRINTER 08076 // attributes on them becuase of the way they were generated below. Make 08077 // sure they get IMPRINTER attributes. 08078 push_named_attributes_to_curves_and_points(temporary_bridges, "IMPRINTER"); 08079 tb_list += temporary_bridges; 08080 GeometryQueryTool::instance()->ige_attribute_after_imprinting(tb_list, body_list); 08081 08082 // Clean up attributes. 08083 remove_imprint_attributes_after_modify(body_sm_list, new_sm_list); 08084 08085 // Restore the virtual geometry. 08086 restore_vg_after_modify(new_sm_list, body_list, gePtr1); 08087 remove_pushed_attributes(new_sm_list, body_list); 08088 } 08089 } 08090 08091 while(temporary_bridges.size()) 08092 { 08093 TopologyBridge* bridge = temporary_bridges.pop(); 08094 bridge->get_geometry_query_engine()->delete_topology_bridge(bridge); 08095 } 08096 08097 status = finish_sm_op(body_list, new_sm_list, new_body_list); 08098 08099 if(process_composites) 08100 do_attribute_cleanup(); 08101 08102 if( CubitUndo::get_undo_enabled() ) 08103 { 08104 if( status == CUBIT_SUCCESS ) 08105 CubitUndo::note_result_bodies( new_body_list ); 08106 else 08107 CubitUndo::remove_last_undo(); 08108 } 08109 08110 return status; 08111 } 08112 08113 CubitStatus GeometryModifyTool::imprint( DLIList<RefFace*> &ref_face_list, 08114 DLIList<RefEdge*> &ref_edge_list, 08115 DLIList<Body*>& new_body_list, 08116 CubitBoolean keep_old_body ) 08117 { 08118 for(int j=0;j<ref_edge_list.size();j++) 08119 { 08120 RefEdge* edge=ref_edge_list[j]; 08121 if(edge->get_arc_length()<=edge->get_geometry_query_engine()->get_sme_resabs_tolerance()) 08122 { 08123 08124 PRINT_ERROR( "Curve %d has zero length.\n To imprint curve as a hard point use the vertex of the curve.\n",edge->id() ); 08125 return CUBIT_FAILURE; 08126 08127 } 08128 } 08129 08130 //get the owning bodies of the faces and edges 08131 DLIList<Body*> body_list; 08132 int j; 08133 for(j=ref_face_list.size(); j--;) 08134 ref_face_list.get_and_step()->bodies( body_list ); 08135 for(j=ref_edge_list.size(); j--;) 08136 ref_edge_list.get_and_step()->bodies( body_list ); 08137 body_list.uniquify_ordered(); 08138 if (!okay_to_modify( body_list, "IMPRINT" )) 08139 return CUBIT_FAILURE; 08140 08141 DLIList<TopologyEntity*> temp_list, temp_list_2, body_me_list; 08142 CAST_LIST_TO_PARENT(ref_face_list, temp_list); 08143 CAST_LIST_TO_PARENT(ref_edge_list, temp_list_2); 08144 temp_list += temp_list_2; 08145 ModelQueryEngine::instance()->query_model(temp_list, DagType::body_type(), body_me_list ); 08146 08147 DLIList<Surface*> surf_list(ref_face_list.size()); 08148 DLIList<Curve*> curve_list(ref_edge_list.size()); 08149 GeometryModifyEngine* gePtr1 = common_modify_engine( ref_face_list,ref_edge_list,surf_list, 08150 curve_list,true); 08151 if ( !gePtr1 ) 08152 { 08153 PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n" 08154 "different modeling engines is not allowed.\n" 08155 "Delete uncommon geometry on these volumes before operation.\n\n"); 08156 return CUBIT_FAILURE; 08157 } 08158 08159 if( CubitUndo::get_undo_enabled() ) 08160 { 08161 if( keep_old_body ) 08162 CubitUndo::save_state(); 08163 else 08164 CubitUndo::save_state_with_cubit_file( ref_face_list ); 08165 } 08166 08167 int process_composites = 0; 08168 if(contains_composites(body_list)) 08169 process_composites = 1; 08170 08171 int i; 08172 DLIList<BodySM*> body_sm_list; 08173 if(process_composites) 08174 { 08175 // Turn certain attributes on. 08176 do_attribute_setup(); 08177 for(i=body_list.size(); i--;) 08178 body_sm_list.append_unique(body_list.get_and_step()->get_body_sm_ptr()); 08179 // Push virtual attributes down to solid model topology before 08180 // doing the imprint. 08181 push_attributes_before_modify(body_sm_list); 08182 // Put "ORIGINAL" attributes on the bodies being imprinted and 08183 // the curves as these originally existed. 08184 DLIList<TopologyBridge*> tmp_tb_list; 08185 CAST_LIST(surf_list, tmp_tb_list, TopologyBridge); 08186 push_named_attributes_to_curves_and_points(tmp_tb_list, "ORIGINAL"); 08187 } 08188 08189 DLIList<BodySM*> new_sm_list; 08190 // The bridges doing the imprinting often get split during the process but 08191 // because of the way we are making copies, the IMPRINTER attribute doesn't 08192 // get propagated to them. temporary_bridges will be filled in with any 08193 // additional IMPRINTER bridges we need to consider below when deciding whether to 08194 // keep composite attributes. 08195 DLIList<TopologyBridge*> temporary_bridges; 08196 CubitStatus status = gePtr1->imprint( surf_list, curve_list, temporary_bridges, 08197 new_sm_list, keep_old_body ); 08198 temporary_bridges.uniquify_ordered(); 08199 08200 if(process_composites) 08201 { 08202 // Analyze the results and adjust virtual attributes as necessary. 08203 DLIList<TopologyBridge*> tb_list; 08204 CAST_LIST(new_sm_list, tb_list, TopologyBridge); 08205 // The bridges coming back in temporary_bridges may not have IMPRINTER 08206 // attributes on them becuase of the way they were generated below. Make 08207 // sure they get IMPRINTER attributes. 08208 push_named_attributes_to_curves_and_points(temporary_bridges, "IMPRINTER"); 08209 tb_list += temporary_bridges; 08210 GeometryQueryTool::instance()->ige_attribute_after_imprinting(tb_list, body_list); 08211 08212 // Clean up attributes. 08213 remove_imprint_attributes_after_modify(body_sm_list, new_sm_list); 08214 08215 restore_vg_after_modify(body_sm_list, body_list, gePtr1); 08216 remove_pushed_attributes(body_sm_list, body_list); 08217 } 08218 08219 while(temporary_bridges.size()) 08220 { 08221 TopologyBridge* bridge = temporary_bridges.pop(); 08222 bridge->get_geometry_query_engine()->delete_topology_bridge(bridge); 08223 } 08224 08225 CubitStatus status2 = finish_sm_op(body_list, new_sm_list, new_body_list); 08226 08227 if(process_composites) 08228 do_attribute_cleanup(); 08229 08230 if( CubitUndo::get_undo_enabled() ) 08231 { 08232 if( status == CUBIT_SUCCESS ) 08233 CubitUndo::note_result_bodies( new_body_list ); 08234 else 08235 CubitUndo::remove_last_undo(); 08236 } 08237 08238 if( status == CUBIT_SUCCESS && status2 == CUBIT_SUCCESS) 08239 return status; 08240 08241 else 08242 return CUBIT_FAILURE; 08243 } 08244 08245 CubitStatus GeometryModifyTool::imprint( DLIList<Surface*> &surface_list, 08246 DLIList<DLIList<Curve*>*> &curve_lists_list, 08247 Body*& /*new_body*/, 08248 CubitBoolean keep_old_body, 08249 CubitBoolean expand) 08250 { 08251 int i; 08252 DLIList<Curve*> *curve_list_ptr; 08253 08254 // Check to see if any curves exist - if none, just exit 08255 int have_curves = 0; 08256 for( i=curve_lists_list.size(); i--; ) 08257 { 08258 curve_list_ptr = curve_lists_list.get_and_step(); 08259 for(int j=0;j<curve_list_ptr->size();j++) 08260 { 08261 Curve* curve=(*curve_list_ptr)[j]; 08262 if(curve->get_arc_length()<=curve->get_geometry_query_engine()->get_sme_resabs_tolerance()) 08263 { 08264 RefEdge* edge = dynamic_cast<RefEdge*>(curve->topology_entity()); 08265 if(edge) 08266 { 08267 PRINT_ERROR( "Curve %d has zero length.\n To imprint as a hard point use the vertex of the curve.\n",edge->id() ); 08268 return CUBIT_FAILURE; 08269 } 08270 else 08271 { 08272 return CUBIT_FAILURE; 08273 } 08274 } 08275 else 08276 { 08277 have_curves++; 08278 break; 08279 } 08280 } 08281 } 08282 if( !have_curves ) 08283 return CUBIT_SUCCESS; 08284 08285 // Get parent bodies 08286 DLIList<Body*> old_body_list; 08287 surface_list.reset(); 08288 for( i=surface_list.size(); i--; ) 08289 { 08290 Surface *surf_ptr = surface_list.get_and_step(); 08291 RefEntity* ref_ent = dynamic_cast<RefEntity*>(surf_ptr->topology_entity()); 08292 RefFace *ref_face_ptr = CAST_TO( ref_ent, RefFace ); 08293 08294 if( ref_face_ptr ) 08295 { 08296 DLIList<Body*> body_list; 08297 ref_face_ptr->bodies( body_list ); 08298 old_body_list.merge_unique( body_list ); 08299 } 08300 } 08301 08302 if( old_body_list.size() > 1 ) 08303 { 08304 PRINT_ERROR( "This operation requires all surfaces to be from the same volume\n" ); 08305 // Note: this restriction could be pretty easily lifted by sorting the 08306 // input lists and calling the GeometryModifyEngine for each body 08307 // separately, or having engines handle this. 08308 return CUBIT_FAILURE; 08309 } 08310 08311 08312 // In order to support imprinting on composite surfaces we will 08313 // get any surfaces underlying the surfaces passed in. For now 08314 // we will only do this if a single surface is coming in but 08315 // it could be extended for multiple surfaces as well. 08316 DLIList<Surface*> new_surface_list; 08317 if(surface_list.size() == 1) 08318 { 08319 GeometryQueryEngine *gqe = surface_list.get()->get_geometry_query_engine(); 08320 DLIList<TopologyBridge*> tbs; 08321 gqe->get_underlying_surfaces(surface_list.get(), tbs); 08322 if(tbs.size() > 0) 08323 { 08324 for(int k=tbs.size(); k--;) 08325 new_surface_list.append(dynamic_cast<Surface*>(tbs.get_and_step())); 08326 } 08327 else 08328 new_surface_list.append(surface_list.get()); 08329 } 08330 else 08331 new_surface_list = surface_list; 08332 08333 // Check engines - must all be the same 08334 GeometryModifyEngine* gme; 08335 new_surface_list.reset(); 08336 gme = get_engine( new_surface_list.get() ); 08337 for( i=new_surface_list.size(); i--; ) 08338 { 08339 Surface *surf_ptr = new_surface_list.get_and_step(); 08340 GeometryModifyEngine* gme2 = get_engine( surf_ptr ); 08341 if( gme != gme2 ) 08342 { 08343 PRINT_ERROR( "All surfaces being imprinted must be from the same geometry engine\n" ); 08344 return CUBIT_FAILURE; 08345 } 08346 } 08347 08348 int j; 08349 for( i=curve_lists_list.size(); i--; ) 08350 { 08351 curve_list_ptr = curve_lists_list.get_and_step(); 08352 for( j=curve_list_ptr->size(); j--; ) 08353 { 08354 Curve *curve_ptr = curve_list_ptr->get_and_step(); 08355 GeometryModifyEngine* gme2 = get_engine( curve_ptr ); 08356 if( gme != gme2 ) 08357 { 08358 PRINT_ERROR( "Curves used to imprint must be from same geometry engine as Surface\n" ); 08359 return CUBIT_FAILURE; 08360 } 08361 } 08362 } 08363 08364 if( CubitUndo::get_undo_enabled() ) 08365 { 08366 if( keep_old_body ) 08367 CubitUndo::save_state(); 08368 else 08369 CubitUndo::save_state_with_cubit_file( old_body_list ); 08370 } 08371 08372 int process_composites = 0; 08373 if(contains_composites(old_body_list)) 08374 process_composites = 1; 08375 08376 BodySM* new_body_sm = 0; 08377 DLIList<BodySM*> body_sm_list; 08378 08379 DLIList<TopologyBridge*> tb_list; 08380 if(process_composites) 08381 { 08382 do_attribute_setup(); 08383 for(i=old_body_list.size(); i--;) 08384 body_sm_list.append_unique(old_body_list.get_and_step()->get_body_sm_ptr()); 08385 push_attributes_before_modify(body_sm_list); 08386 // push_imprint_attributes_before_modify(body_sm_list); 08387 DLIList<TopologyBridge*> tmp_tb_list; 08388 CAST_LIST(new_surface_list, tmp_tb_list, TopologyBridge); 08389 push_named_attributes_to_curves_and_points(tmp_tb_list, "ORIGINAL"); 08390 08391 for(i=curve_lists_list.size(); i>0; i--) 08392 { 08393 DLIList<Curve*> *cur_list = curve_lists_list.get_and_step(); 08394 for(j=cur_list->size(); j>0; j--) 08395 { 08396 Curve *cur_curve = cur_list->get_and_step(); 08397 tb_list.append(cur_curve); 08398 } 08399 } 08400 push_named_attributes_to_curves_and_points(tb_list, "IMPRINTER"); 08401 } 08402 08403 CubitStatus status = gme->imprint( new_surface_list, curve_lists_list, 08404 new_body_sm, keep_old_body, expand); 08405 08406 DLIList<Body*> new_body_list; 08407 DLIList<BodySM*> new_sm_list; 08408 new_sm_list.append( new_body_sm ); 08409 08410 if(process_composites) 08411 { 08412 // Analyze the results and adjust virtual attributes as necessary. 08413 DLIList<TopologyBridge*> tmp_tb_list; 08414 CAST_LIST(new_sm_list, tmp_tb_list, TopologyBridge); 08415 tb_list += tmp_tb_list; 08416 GeometryQueryTool::instance()->ige_attribute_after_imprinting(tb_list, old_body_list); 08417 08418 // Clean up attributes. 08419 remove_imprint_attributes_after_modify(body_sm_list, new_sm_list); 08420 08421 restore_vg_after_modify(body_sm_list, old_body_list, gme); 08422 remove_pushed_attributes(body_sm_list, old_body_list); 08423 } 08424 08425 CubitStatus status2 = finish_sm_op(old_body_list, new_sm_list, new_body_list); 08426 08427 if(process_composites) 08428 do_attribute_cleanup(); 08429 08430 if( CubitUndo::get_undo_enabled() ) 08431 { 08432 if( status == CUBIT_SUCCESS ) 08433 CubitUndo::note_result_bodies( new_body_list ); 08434 else 08435 CubitUndo::remove_last_undo(); 08436 } 08437 08438 if( status == CUBIT_SUCCESS && status2 == CUBIT_SUCCESS) 08439 return status; 08440 08441 else 08442 return CUBIT_FAILURE; 08443 } 08444 08445 CubitStatus GeometryModifyTool::imprint( DLIList<Body*> &body_list, 08446 DLIList<CubitVector> &vector_list, 08447 DLIList<Body*>& new_body_list, 08448 CubitBoolean keep_old_body, 08449 CubitBoolean merge ) 08450 { 08451 // Check the GeometryEngine for each of the RefEdges; check to 08452 // make sure they're all the same 08453 body_list.reset(); 08454 08455 if (!okay_to_modify( body_list, "IMPRINT" )) 08456 return CUBIT_FAILURE; 08457 08458 DLIList<BodySM*> body_sm_list(body_list.size()), new_sm_list; 08459 GeometryModifyEngine* gePtr1 = common_modify_engine(body_list, body_sm_list); 08460 if ( !gePtr1 ) 08461 { 08462 PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n" 08463 "different modeling engines is not allowed.\n" 08464 "Delete uncommon geometry on these volumes before operation.\n\n"); 08465 return CUBIT_FAILURE; 08466 } 08467 08468 if( CubitUndo::get_undo_enabled() ) 08469 { 08470 if( keep_old_body ) 08471 CubitUndo::save_state(); 08472 else 08473 CubitUndo::save_state_with_cubit_file( body_list ); 08474 } 08475 08476 int process_composites = 0; 08477 if(contains_composites(body_list)) 08478 process_composites = 1; 08479 08480 int i; 08481 DLIList<TopologyBridge*> temporary_bridges; 08482 if(process_composites) 08483 { 08484 // Turn certain attributes on. 08485 do_attribute_setup(); 08486 // Push virtual attributes down to solid model topology before 08487 // doing the imprint. 08488 push_attributes_before_modify(body_sm_list); 08489 // Create temporary bridges for the vector positions. We do 08490 // this so that we can put an IMPRINTER attribute on them 08491 // and use them later for deciding whether to keep composite 08492 // attributes or not. 08493 for(i=vector_list.size(); i>0; i--) 08494 { 08495 CubitVector vec = vector_list.get_and_step(); 08496 TBPoint *pt = gePtr1->make_Point(vec); 08497 temporary_bridges.append(pt); 08498 } 08499 push_named_attributes_to_curves_and_points(temporary_bridges, "IMPRINTER"); 08500 DLIList<TopologyBridge*> tmp_tb_list; 08501 CAST_LIST(body_sm_list, tmp_tb_list, TopologyBridge); 08502 // Put "ORIGINAL" attributes on the bridges that originally existed. 08503 push_named_attributes_to_curves_and_points(tmp_tb_list, "ORIGINAL"); 08504 } 08505 08506 CubitStatus status = gePtr1->imprint( body_sm_list, vector_list,new_sm_list, 08507 keep_old_body); 08508 08509 temporary_bridges.uniquify_ordered(); 08510 08511 if(process_composites) 08512 { 08513 // Analyze the results and adjust virtual attributes as necessary. 08514 DLIList<TopologyBridge*> tb_list; 08515 CAST_LIST(new_sm_list, tb_list, TopologyBridge); 08516 tb_list += temporary_bridges; 08517 GeometryQueryTool::instance()->ige_attribute_after_imprinting(tb_list, body_list); 08518 08519 while(temporary_bridges.size()) 08520 { 08521 TopologyBridge* bridge = temporary_bridges.pop(); 08522 bridge->get_geometry_query_engine()->delete_topology_bridge(bridge); 08523 } 08524 08525 // Clean up attributes. 08526 remove_imprint_attributes_after_modify(body_sm_list, new_sm_list); 08527 08528 // Restore the virtual geometry. 08529 restore_vg_after_modify(new_sm_list, body_list, gePtr1); 08530 remove_pushed_attributes(new_sm_list, body_list); 08531 } 08532 08533 CubitStatus status2 = finish_sm_op(body_list, new_sm_list, new_body_list); 08534 08535 if(process_composites) 08536 do_attribute_cleanup(); 08537 08538 if( merge ) 08539 { 08540 DLIList<Body*> bodies_to_merge; 08541 int i; 08542 for( i=new_body_list.size(); i--; ) 08543 { 08544 Body *tmp_body = new_body_list.get_and_step(); 08545 DLIList<RefEdge*> ref_edge_list; 08546 tmp_body->ref_edges( ref_edge_list ); 08547 08548 int j; 08549 for( j=ref_edge_list.size(); j--; ) 08550 { 08551 RefEdge *tmp_edge = ref_edge_list.get_and_step(); 08552 DLIList<Body*> body_list; 08553 tmp_edge->bodies( body_list ); 08554 bodies_to_merge.merge_unique( body_list ); 08555 } 08556 } 08557 MergeTool::instance()->merge_bodies( bodies_to_merge ); 08558 } 08559 08560 if( CubitUndo::get_undo_enabled() ) 08561 { 08562 if( status == CUBIT_SUCCESS ) 08563 CubitUndo::note_result_bodies( new_body_list ); 08564 else 08565 CubitUndo::remove_last_undo(); 08566 } 08567 08568 if( status == CUBIT_SUCCESS && status2 == CUBIT_SUCCESS) 08569 return status; 08570 08571 else 08572 return CUBIT_FAILURE; 08573 } 08574 CubitStatus GeometryModifyTool::project_edges( DLIList<RefFace*> &ref_face_list, 08575 DLIList<RefEdge*> &ref_edge_list_in, 08576 DLIList<RefEdge*> &ref_edge_list_new, 08577 CubitBoolean trim_projected) 08578 { 08579 int i, j; 08580 08581 // Check the GeometryEngine for each of the RefEdges; check to 08582 // make sure they're all the same 08583 DLIList<Surface*> surface_list(ref_face_list.size()); 08584 DLIList<Curve*> curve_list_in(ref_edge_list_in.size()), curve_list_new; 08585 GeometryModifyEngine* gme = common_modify_engine( ref_face_list, 08586 ref_edge_list_in, 08587 surface_list, 08588 curve_list_in ); 08589 08590 if ( !gme ) { 08591 PRINT_ERROR("In GeometryTool::create_blend\n" 08592 " Curves have different modify engines.\n"); 08593 return CUBIT_FAILURE; 08594 } 08595 08596 CubitStatus status = gme-> 08597 project_edges( surface_list, curve_list_in, curve_list_new); 08598 08599 if( CubitUndo::get_undo_enabled() && status == CUBIT_SUCCESS ) 08600 CubitUndo::save_state(); 08601 08602 08603 curve_list_new.reset(); 08604 08605 if(trim_projected){ 08606 DLIList<Curve*> tmp_curves, all_new_curves; 08607 Curve* tmp_curve; 08608 Surface* tmp_surface; 08609 08610 for(i = 0; i< surface_list.size(); i++){ 08611 tmp_curves.clean_out(); 08612 tmp_surface = surface_list.get_and_step(); 08613 for(j=0; j<curve_list_new.size(); j++){ 08614 tmp_curve = curve_list_new.get_and_step(); 08615 status = gme->curve_surface_intersection( tmp_surface, tmp_curve, tmp_curves); 08616 } 08617 all_new_curves += tmp_curves; 08618 08619 } 08620 08621 if(!all_new_curves.size()){ 08622 if(!curve_list_new.size()){ 08623 PRINT_ERROR("Projection resulted in no curves.\n"); 08624 return CUBIT_FAILURE; 08625 } 08626 else{ 08627 PRINT_WARNING("No curve remained after trimming operation. \n \tCurve projection may lie completely outside of trimmed surface.\n"); 08628 } 08629 } 08630 08631 //fix this... 08632 //can we just cleanout this list or do we need to delete the entities in it. 08633 for( i = 0; i< curve_list_new.size(); i++ ) 08634 { 08635 Curve *tmp_curve = curve_list_new.get_and_step(); 08636 gme->get_gqe()->delete_solid_model_entities( tmp_curve ); 08637 } 08638 08639 curve_list_new.clean_out(); 08640 curve_list_new = all_new_curves; 08641 08642 if( CubitUndo::get_undo_enabled() && status == CUBIT_SUCCESS ) 08643 CubitUndo::save_state(); 08644 } 08645 08646 08647 08648 curve_list_new.reset(); 08649 for (i = curve_list_new.size(); i--; ) 08650 { 08651 Curve* curve = curve_list_new.get_and_step(); 08652 RefEdge* new_edge = GeometryQueryTool::instance()->make_free_RefEdge(curve); 08653 PRINT_INFO("Created Curve %d\n", new_edge->id()); 08654 ref_edge_list_new.append(new_edge); 08655 if( CubitUndo::get_undo_enabled() && new_edge ) 08656 CubitUndo::note_result_entity( new_edge ); 08657 } 08658 08659 if( CubitUndo::get_undo_enabled() ) 08660 { 08661 if( ref_edge_list_new.size() == 0 ) 08662 CubitUndo::remove_last_undo(); 08663 } 08664 08665 return status; 08666 } 08667 08668 CubitStatus 08669 GeometryModifyTool::imprint_projected_edges(DLIList<RefFace*> &ref_face_list, 08670 DLIList<RefEdge*> &ref_edge_list_in, 08671 DLIList<Body*>& new_body_list, 08672 CubitBoolean keep_old_body, 08673 CubitBoolean keep_free_edges) 08674 { 08675 08676 DLIList<Surface*> surface_list(ref_face_list.size()); 08677 DLIList<Curve*> curve_list(ref_edge_list_in.size()); 08678 GeometryModifyEngine* gme = common_modify_engine( ref_face_list, 08679 ref_edge_list_in, 08680 surface_list, 08681 curve_list ); 08682 if ( !gme ) 08683 { 08684 PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n" 08685 "different modeling engines is not allowed.\n" 08686 "Delete uncommon geometry on these volumes before operation.\n\n"); 08687 return CUBIT_FAILURE; 08688 } 08689 08690 DLIList<TopologyEntity*> query_output, query_input(ref_face_list.size()); 08691 CAST_LIST_TO_PARENT(ref_face_list, query_input); 08692 ModelQueryEngine::instance()->query_model(query_input, DagType::body_type(), query_output); 08693 DLIList<Body*> body_list(query_output.size()); 08694 CAST_LIST(query_output, body_list, Body); 08695 DLIList<BodySM*> new_sm_list; 08696 DLIList<Curve*> kept_free_edges; 08697 08698 if( CubitUndo::get_undo_enabled() ) 08699 { 08700 if( keep_old_body ) 08701 CubitUndo::save_state(); 08702 else 08703 CubitUndo::save_state_with_cubit_file( ref_face_list ); 08704 } 08705 08706 CubitStatus status = gme->imprint_projected_edges( surface_list, curve_list, 08707 new_sm_list, kept_free_edges, 08708 keep_old_body, keep_free_edges); 08709 08710 if (!finish_sm_op(body_list, new_sm_list, new_body_list)) 08711 status = CUBIT_FAILURE; 08712 08713 DLIList<RefEdge*> kept_ref_edges; 08714 if( keep_free_edges ) 08715 { 08716 for( int i=kept_free_edges.size(); i--; ) 08717 { 08718 RefEdge *tmp_edge = GeometryQueryTool::instance()->make_free_RefEdge( kept_free_edges.get_and_step()); 08719 if( tmp_edge ) 08720 kept_ref_edges.append(tmp_edge ); 08721 } 08722 } 08723 08724 if( CubitUndo::get_undo_enabled() ) 08725 { 08726 if( status == CUBIT_FAILURE ) 08727 CubitUndo::remove_last_undo(); 08728 else 08729 { 08730 CubitUndo::note_result_bodies( new_body_list ); 08731 if( keep_free_edges ) 08732 { 08733 DLIList<RefEntity*> ref_ents; 08734 for( int i=kept_ref_edges.size(); i--; ) 08735 ref_ents.append( kept_ref_edges.get_and_step() ); 08736 CubitUndo::note_result_entities( ref_ents ); 08737 } 08738 } 08739 } 08740 08741 return status; 08742 } 08743 08744 CubitStatus 08745 GeometryModifyTool::imprint_projected_edges(DLIList<RefFace*> &ref_face_list, 08746 DLIList<Body*> &body_list, 08747 DLIList<RefEdge*> &ref_edge_list_in, 08748 DLIList<Body*>& new_body_list, 08749 CubitBoolean keep_old_body, 08750 CubitBoolean keep_free_edges) 08751 { 08752 08753 DLIList<Surface*> surface_list(ref_face_list.size()); 08754 DLIList<Curve*> curve_list(ref_edge_list_in.size()); 08755 DLIList<BodySM*> body_sm_list(body_list.size()), new_sm_list; 08756 GeometryModifyEngine* gme = common_modify_engine(ref_face_list, 08757 ref_edge_list_in, 08758 surface_list, 08759 curve_list); 08760 if (!gme || gme != common_modify_engine(body_list, body_sm_list)) 08761 { 08762 PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n" 08763 "different modeling engines is not allowed.\n" 08764 "Delete uncommon geometry on these volumes before operation.\n\n"); 08765 return CUBIT_FAILURE; 08766 } 08767 08768 // Get RefFace bodies 08769 DLIList<TopologyEntity*> query_output, query_input(ref_face_list.size()); 08770 CAST_LIST_TO_PARENT(ref_face_list, query_input); 08771 ModelQueryEngine::instance()-> 08772 query_model( query_input, DagType::body_type(), query_output ); 08773 DLIList<Body*> face_body_list; 08774 CAST_LIST(query_output, face_body_list, Body); 08775 08776 CubitStatus status = gme->imprint_projected_edges( surface_list, 08777 body_sm_list, 08778 curve_list, 08779 new_sm_list, 08780 keep_old_body, 08781 keep_free_edges); 08782 face_body_list += body_list; 08783 if (!finish_sm_op(face_body_list, new_sm_list, new_body_list)) 08784 status = CUBIT_FAILURE; 08785 08786 return status; 08787 08788 } 08789 08790 08791 RefEntity* GeometryModifyTool::copy_refentity( RefEntity *old_entity ) 08792 { 08793 RefEntity *new_entity = NULL; 08794 08795 if( old_entity == NULL ) 08796 return (RefEntity*) NULL; 08797 08798 if( CAST_TO( old_entity, RefVolume ) ) 08799 return (RefEntity*) NULL; 08800 08801 RefFace *old_face = CAST_TO( old_entity, RefFace ); 08802 if( old_face ) 08803 { 08804 RefFace *new_face = instance()->make_RefFace( old_face ); 08805 new_entity = CAST_TO( new_face, RefEntity ); 08806 } 08807 08808 RefEdge *old_edge = CAST_TO( old_entity, RefEdge ); 08809 if( old_edge ) 08810 { 08811 RefEdge *new_edge = instance()->make_RefEdge( old_edge ); 08812 new_entity = CAST_TO( new_edge, RefEntity ); 08813 } 08814 08815 RefVertex *old_vert = CAST_TO( old_entity, RefVertex ); 08816 if( old_vert ) 08817 { 08818 RefVertex *new_vert = instance()->make_RefVertex( old_vert->coordinates() ); 08819 new_entity = CAST_TO( new_vert, RefEntity ); 08820 } 08821 08822 return new_entity; 08823 } 08824 08825 // Calls solid modeling engine to webcut with a sheet body. 08826 CubitStatus GeometryModifyTool::webcut_with_sheet( DLIList<Body*> &webcut_body_list, 08827 Body *sheet_body, 08828 DLIList<Body*> &new_bodies, 08829 DLIList<Body*> &neighboring_bodies, 08830 ImprintType imprint_type, 08831 CubitBoolean merge, 08832 CubitBoolean preview) 08833 { 08834 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 08835 return CUBIT_FAILURE; 08836 08837 GfxPreview::clear(); 08838 08839 //remove any bodies with bbox that does not intersect tool body bbox 08840 CubitBox tool_bounding_box = sheet_body->bounding_box(); 08841 remove_bodies_outside_bounding_box( webcut_body_list, tool_bounding_box ); 08842 08843 if( webcut_body_list.size() == 0 ) 08844 { 08845 PRINT_INFO("Tool does not intersect any bodies/volumes.\n"); 08846 return CUBIT_FAILURE; 08847 } 08848 08849 DLIList<Body*> original_body_list = webcut_body_list; 08850 webcut_body_list.append(sheet_body); 08851 DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms; 08852 GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list); 08853 if ( !gme ) 08854 { 08855 PRINT_ERROR("Performing WEBCUTS with volumes containing geometry from\n" 08856 "different modeling engines is not allowed.\n" 08857 "Delete uncommon geometry on these volumes before operation.\n\n"); 08858 return CUBIT_FAILURE; 08859 } 08860 BodySM* tool_sm = body_sm_list.pop(); 08861 08862 DLIList<int> merged_surface_ids; 08863 DLIList<int> merged_curve_ids; 08864 DLIList<BodySM*> neighbor_imprint_list; 08865 DLIList<Body*> bodies_to_modify; 08866 08867 if (!preview) 08868 { 08869 if( CubitUndo::get_undo_enabled() ) 08870 { 08871 DLIList<Body*> bodies_to_save; 08872 bodies_to_save += webcut_body_list; 08873 bodies_to_save += neighboring_bodies; 08874 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 08875 } 08876 08877 int i; 08878 for( i=neighboring_bodies.size(); i--; ) 08879 { 08880 Body *neighbor_body = neighboring_bodies.get_and_step(); 08881 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 08882 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 08883 08884 if( gme == neighbor_gme ) 08885 neighbor_imprint_list.append( tmp_body ); 08886 } 08887 08888 do_attribute_setup(); 08889 DLIList<BodySM*> bodies_sm_to_modify; 08890 bodies_sm_to_modify += body_sm_list; 08891 bodies_sm_to_modify += neighbor_imprint_list; 08892 push_attributes_before_modify( bodies_sm_to_modify ); 08893 bodies_to_modify += webcut_body_list; 08894 bodies_to_modify += neighboring_bodies; 08895 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 08896 } 08897 08898 CubitStatus stat = gme->webcut ( 08899 body_sm_list, tool_sm, neighbor_imprint_list, 08900 new_sms, imprint_type, preview ); 08901 08902 if (!preview) 08903 { 08904 restore_vg_after_modify(new_sms, bodies_to_modify, gme); 08905 remove_pushed_attributes(new_sms, bodies_to_modify ); 08906 } 08907 08908 if( stat == CUBIT_FAILURE ) 08909 { 08910 do_attribute_cleanup(); 08911 08912 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 08913 { 08914 if( stat == CUBIT_SUCCESS ) 08915 CubitUndo::note_result_bodies( new_bodies ); 08916 else 08917 CubitUndo::remove_last_undo(); 08918 } 08919 return CUBIT_FAILURE; 08920 } 08921 08922 // finish up if not a preview 08923 if (!preview) 08924 { 08925 stat = finish_webcut( webcut_body_list, new_sms, merge, stat, new_bodies, 08926 &merged_surface_ids, &merged_curve_ids ); 08927 // leave webcut_body_list as we found it -- remove appended tool body 08928 webcut_body_list.pop(); 08929 08930 do_attribute_cleanup(); 08931 08932 if( CubitUndo::get_undo_enabled() ) 08933 { 08934 if( stat == CUBIT_SUCCESS ) 08935 CubitUndo::note_result_bodies( new_bodies ); 08936 else 08937 CubitUndo::remove_last_undo(); 08938 } 08939 } 08940 08941 08942 return stat; 08943 } 08944 // Calls solid modeling engine to webcut with a sheet body. 08945 CubitStatus GeometryModifyTool::webcut_with_extended_sheet( DLIList<Body*> &webcut_body_list, 08946 DLIList<RefFace*> &ref_face_list, 08947 DLIList<Body*> &new_bodies, 08948 DLIList<Body*> &neighboring_bodies, 08949 int &num_cut, 08950 ImprintType imprint_type, 08951 CubitBoolean merge, 08952 CubitBoolean preview) 08953 { 08954 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 08955 return CUBIT_FAILURE; 08956 08957 GfxPreview::clear(); 08958 08959 DLIList<RefEntity*> ref_entity_list; 08960 CAST_LIST( ref_face_list, ref_entity_list, RefEntity ); 08961 if( !same_modify_engine( ref_entity_list ) ) 08962 { 08963 PRINT_ERROR( "Extending surfaces from different geometry engines is\n" 08964 " not allowed.\n\n" ); 08965 return CUBIT_FAILURE; 08966 } 08967 08968 DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms; 08969 GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list); 08970 08971 if( !gme ) 08972 { 08973 PRINT_ERROR("Performing WEBCUTS on volumes containing geometry from\n" 08974 "different modeling engines is not allowed.\n" 08975 "Delete uncommon geometry on these volumes before operation.\n\n"); 08976 return CUBIT_FAILURE; 08977 } 08978 08979 const char* modeler = 08980 ref_face_list.get()->get_geometry_query_engine()->modeler_type(); 08981 if (strncmp("virtual", modeler, 7) == 0) 08982 { 08983 PRINT_ERROR("Cannot extend virtual surfaces.\n" 08984 "Remove virtual layer before operation.\n"); 08985 return CUBIT_FAILURE; 08986 } 08987 08988 Surface* surf_ptr = 0; 08989 TopologyBridge* bridge = ref_face_list.get()->bridge_manager()->topology_bridge(gme->get_gqe()); 08990 surf_ptr = dynamic_cast<Surface*>(bridge); 08991 08992 if ( !surf_ptr ) 08993 { 08994 PRINT_ERROR("Performing WEBCUTS on volumes containing geometry from a\n" 08995 "different modeling engine than the extended surfaces is\n" 08996 "not allowed.\n" 08997 "Delete uncommon geometry on these volumes before operation.\n\n"); 08998 return CUBIT_FAILURE; 08999 } 09000 09001 GeometryQueryEngine *gqe = gme->get_gqe(); 09002 09003 int i; 09004 RefFace *ref_face_ptr; 09005 DLIList<Surface*> surf_list; 09006 for( i=ref_face_list.size(); i--; ) 09007 { 09008 ref_face_ptr = ref_face_list.get_and_step(); 09009 bridge = ref_face_ptr->bridge_manager()->topology_bridge(gqe); 09010 surf_ptr = dynamic_cast<Surface*>(bridge); 09011 surf_list.append( surf_ptr ); 09012 } 09013 09014 DLIList<int> merged_surface_ids; 09015 DLIList<int> merged_curve_ids; 09016 DLIList<BodySM*> neighbor_imprint_list; 09017 DLIList<Body*> bodies_to_modify; 09018 09019 if (!preview) 09020 { 09021 if( CubitUndo::get_undo_enabled() ) 09022 { 09023 DLIList<Body*> bodies_to_save; 09024 bodies_to_save += webcut_body_list; 09025 bodies_to_save += neighboring_bodies; 09026 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 09027 } 09028 09029 int i; 09030 for( i=neighboring_bodies.size(); i--; ) 09031 { 09032 Body *neighbor_body = neighboring_bodies.get_and_step(); 09033 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 09034 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 09035 09036 if( gme == neighbor_gme ) 09037 neighbor_imprint_list.append( tmp_body ); 09038 } 09039 09040 do_attribute_setup(); 09041 DLIList<BodySM*> bodies_sm_to_modify; 09042 bodies_sm_to_modify += body_sm_list; 09043 bodies_sm_to_modify += neighbor_imprint_list; 09044 push_attributes_before_modify( bodies_sm_to_modify ); 09045 bodies_to_modify += webcut_body_list; 09046 bodies_to_modify += neighboring_bodies; 09047 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 09048 } 09049 09050 CubitStatus stat = gme->webcut_with_extended_sheet( body_sm_list, 09051 surf_list, neighbor_imprint_list, new_sms, num_cut, imprint_type, 09052 preview ); 09053 09054 if (!preview) 09055 { 09056 restore_vg_after_modify(new_sms, bodies_to_modify, gme); 09057 remove_pushed_attributes(new_sms, bodies_to_modify); 09058 stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies, 09059 &merged_surface_ids, &merged_curve_ids ); 09060 do_attribute_cleanup(); 09061 09062 if( CubitUndo::get_undo_enabled() ) 09063 { 09064 if( stat == CUBIT_SUCCESS ) 09065 CubitUndo::note_result_bodies( new_bodies ); 09066 else 09067 CubitUndo::remove_last_undo(); 09068 } 09069 } 09070 09071 return stat; 09072 } 09073 09074 09075 CubitStatus GeometryModifyTool::webcut_with_sweep_surfaces_rotated( 09076 DLIList<Body*> &webcut_body_list, 09077 DLIList<RefFace*> &tool_faces, 09078 CubitVector &point, 09079 CubitVector &sweep_axis, 09080 double angle, 09081 RefFace* stop_surf, 09082 bool up_to_next, 09083 DLIList<Body*> &new_bodies, 09084 DLIList<Body*> &neighboring_bodies, 09085 ImprintType imprint_type, 09086 CubitBoolean merge, 09087 CubitBoolean preview) 09088 { 09089 09090 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 09091 return CUBIT_FAILURE; 09092 09093 GfxPreview::clear(); 09094 09095 DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms; 09096 GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list); 09097 DLIList<Surface*> surfaces_to_sweep; 09098 if (gme) 09099 { 09100 GeometryModifyEngine* surf_gme = common_modify_engine( tool_faces, surfaces_to_sweep ); 09101 if( gme != surf_gme ) 09102 PRINT_ERROR("All geometry not from the same modeling engine.\n"); 09103 } 09104 09105 Surface *stop_surface = NULL; 09106 if( stop_surf ) 09107 { 09108 GeometryModifyEngine *tmp_gme = get_engine(stop_surf); 09109 09110 if( gme != tmp_gme ) 09111 { 09112 PRINT_ERROR("Stop surface %d is not of same modeling engine as other input geometry.\n", 09113 stop_surf->id() ); 09114 return CUBIT_FAILURE; 09115 } 09116 09117 stop_surface = stop_surf->get_surface_ptr(); 09118 } 09119 09120 DLIList<int> merged_surface_ids; 09121 DLIList<int> merged_curve_ids; 09122 DLIList<BodySM*> neighbor_imprint_list; 09123 DLIList<Body*> bodies_to_modify; 09124 09125 if (!preview) 09126 { 09127 if( CubitUndo::get_undo_enabled() ) 09128 { 09129 DLIList<Body*> bodies_to_save; 09130 bodies_to_save += webcut_body_list; 09131 bodies_to_save += neighboring_bodies; 09132 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 09133 } 09134 09135 int i; 09136 for( i=neighboring_bodies.size(); i--; ) 09137 { 09138 Body *neighbor_body = neighboring_bodies.get_and_step(); 09139 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 09140 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 09141 09142 if( gme == neighbor_gme ) 09143 neighbor_imprint_list.append( tmp_body ); 09144 } 09145 09146 do_attribute_setup(); 09147 DLIList<BodySM*> bodies_sm_to_modify; 09148 bodies_sm_to_modify += body_sm_list; 09149 bodies_sm_to_modify += neighbor_imprint_list; 09150 push_attributes_before_modify( bodies_sm_to_modify ); 09151 bodies_to_modify += webcut_body_list; 09152 bodies_to_modify += neighboring_bodies; 09153 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 09154 } 09155 09156 BodySM* cutting_tool_ptr = NULL; 09157 CubitStatus stat = prepare_surface_sweep(body_sm_list,surfaces_to_sweep, 09158 sweep_axis,false,false,false, 09159 up_to_next,stop_surface, NULL, cutting_tool_ptr, &point, &angle); 09160 if(stat == CUBIT_SUCCESS ) 09161 { 09162 stat = gme->webcut( body_sm_list, cutting_tool_ptr, neighbor_imprint_list, 09163 new_sms, imprint_type, preview ); 09164 09165 // Delete the BodySM that was created to be used as a tool 09166 gme->get_gqe()->delete_solid_model_entities(cutting_tool_ptr) ; 09167 } 09168 09169 else 09170 { 09171 PRINT_ERROR("Can't create a swept surface for webcut.\n"); 09172 return CUBIT_FAILURE; 09173 } 09174 09175 // if not previewing do the rest of the creation 09176 if (!preview) 09177 { 09178 restore_vg_after_modify(new_sms, bodies_to_modify, gme); 09179 remove_pushed_attributes(new_sms, bodies_to_modify); 09180 stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies, 09181 &merged_surface_ids, &merged_curve_ids ); 09182 do_attribute_cleanup(); 09183 09184 if( CubitUndo::get_undo_enabled() ) 09185 { 09186 if( stat == CUBIT_SUCCESS ) 09187 CubitUndo::note_result_bodies( new_bodies ); 09188 else 09189 CubitUndo::remove_last_undo(); 09190 } 09191 } 09192 09193 return stat; 09194 } 09195 09196 CubitStatus GeometryModifyTool::webcut_with_sweep_curves_rotated( 09197 DLIList<Body*> &webcut_body_list, 09198 DLIList<RefEdge*> &tool_curves, 09199 CubitVector &point, 09200 CubitVector &sweep_axis, 09201 double angle, 09202 RefFace* stop_surf, 09203 DLIList<Body*> &new_bodies, 09204 DLIList<Body*> &neighboring_bodies, 09205 ImprintType imprint_type, 09206 CubitBoolean merge, 09207 CubitBoolean preview) 09208 { 09209 09210 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 09211 return CUBIT_FAILURE; 09212 09213 GfxPreview::clear(); 09214 09215 DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms; 09216 GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list); 09217 DLIList<Curve*> curves_to_sweep; 09218 if (gme) 09219 { 09220 DLIList<RefFace*> dummy1; 09221 DLIList<Surface*> dummy2; 09222 GeometryModifyEngine* surf_gme = common_modify_engine( dummy1, tool_curves, 09223 dummy2, curves_to_sweep ); 09224 if( gme != surf_gme ) 09225 PRINT_ERROR("All geometry not from the same modeling engine.\n"); 09226 } 09227 09228 Surface *stop_surface = NULL; 09229 if( stop_surf ) 09230 { 09231 GeometryModifyEngine *tmp_gme = get_engine(stop_surf); 09232 09233 if( gme != tmp_gme ) 09234 { 09235 PRINT_ERROR("Stop surface %d is not of same modeling engine as other input geometry.\n", 09236 stop_surf->id() ); 09237 return CUBIT_FAILURE; 09238 } 09239 09240 stop_surface = stop_surf->get_surface_ptr(); 09241 } 09242 09243 DLIList<int> merged_surface_ids; 09244 DLIList<int> merged_curve_ids; 09245 DLIList<BodySM*> neighbor_imprint_list; 09246 DLIList<Body*> bodies_to_modify; 09247 09248 if (!preview) 09249 { 09250 if( CubitUndo::get_undo_enabled() ) 09251 { 09252 DLIList<Body*> bodies_to_save; 09253 bodies_to_save += webcut_body_list; 09254 bodies_to_save += neighboring_bodies; 09255 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 09256 } 09257 09258 int i; 09259 for( i=neighboring_bodies.size(); i--; ) 09260 { 09261 Body *neighbor_body = neighboring_bodies.get_and_step(); 09262 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 09263 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 09264 09265 if( gme == neighbor_gme ) 09266 neighbor_imprint_list.append( tmp_body ); 09267 } 09268 09269 do_attribute_setup(); 09270 DLIList<BodySM*> bodies_sm_to_modify; 09271 bodies_sm_to_modify += body_sm_list; 09272 bodies_sm_to_modify += neighbor_imprint_list; 09273 push_attributes_before_modify( bodies_sm_to_modify ); 09274 bodies_to_modify += webcut_body_list; 09275 bodies_to_modify += neighboring_bodies; 09276 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 09277 } 09278 09279 //sweep the curves. 09280 DLIList<GeometryEntity*> ref_ent_list; 09281 for(int i = 0; i < curves_to_sweep.size(); i++) 09282 ref_ent_list.append((GeometryEntity*)(curves_to_sweep.get_and_step())); 09283 09284 DLIList<BodySM*> swept_bodies; 09285 CubitStatus stat = gme->sweep_rotational(ref_ent_list,swept_bodies,point, 09286 sweep_axis,angle,0, 0.0, 0,false,false, 09287 false,stop_surface); 09288 if(stat == CUBIT_FAILURE && swept_bodies.size() == 0) 09289 return stat; 09290 09291 //stitch faces together 09292 BodySM* cutting_tool_ptr = NULL; 09293 DLIList<BodySM*> cutting_tools; 09294 stat = gme->stitch(swept_bodies, cutting_tools, CUBIT_FALSE, 1E-6); 09295 09296 if(cutting_tools.size() > 1 || cutting_tools.size() == 0) 09297 { 09298 //delete all swept faces 09299 for(int i = 0; i < cutting_tools.size(); i++) 09300 gme->get_gqe()->delete_solid_model_entities(cutting_tools.get_and_step()) ; 09301 return stat; 09302 } 09303 else 09304 { 09305 cutting_tool_ptr = cutting_tools.get(); 09306 stat = gme->webcut( body_sm_list, cutting_tool_ptr, neighbor_imprint_list, 09307 new_sms, imprint_type, preview); 09308 09309 // Delete the BodySM that was created to be used as a tool 09310 gme->get_gqe()->delete_solid_model_entities(cutting_tool_ptr) ; 09311 } 09312 09313 if (!preview) 09314 { 09315 restore_vg_after_modify(new_sms, bodies_to_modify, gme); 09316 remove_pushed_attributes(new_sms, bodies_to_modify); 09317 stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies, 09318 &merged_surface_ids, &merged_curve_ids ); 09319 do_attribute_cleanup(); 09320 09321 if( CubitUndo::get_undo_enabled() ) 09322 { 09323 if( stat == CUBIT_SUCCESS ) 09324 CubitUndo::note_result_bodies( new_bodies ); 09325 else 09326 CubitUndo::remove_last_undo(); 09327 } 09328 } 09329 09330 return stat; 09331 } 09332 09333 CubitStatus GeometryModifyTool::webcut_with_sweep_curves( 09334 DLIList<Body*> &webcut_body_list, 09335 DLIList<RefEdge*> &tool_curves, 09336 const CubitVector sweep_vector, 09337 bool through_all, 09338 RefFace *stop_surf, 09339 RefEdge* edge_to_sweep_along, 09340 DLIList<Body*> &new_bodies, 09341 DLIList<Body*> &neighboring_bodies, 09342 ImprintType imprint_type, 09343 CubitBoolean merge, 09344 CubitBoolean preview) 09345 { 09346 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 09347 return CUBIT_FAILURE; 09348 09349 GfxPreview::clear(); 09350 09351 DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms; 09352 GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list); 09353 DLIList<Curve*> curves_to_sweep; 09354 if (gme) 09355 { 09356 DLIList<RefFace*> dummy1; 09357 DLIList<Surface*> dummy2; 09358 GeometryModifyEngine* surf_gme = common_modify_engine( dummy1, tool_curves, 09359 dummy2, curves_to_sweep ); 09360 if( gme != surf_gme ){ 09361 PRINT_ERROR("All geometry not from the same modeling engine.\n"); 09362 return CUBIT_FAILURE; 09363 } 09364 } 09365 else{ 09366 PRINT_ERROR("All volumes not from the same modeling engine.\n"); 09367 return CUBIT_FAILURE; 09368 } 09369 09370 Surface *stop_surface = NULL; 09371 if( stop_surf ) 09372 { 09373 GeometryModifyEngine *tmp_gme = get_engine(stop_surf); 09374 09375 if( gme != tmp_gme ) 09376 { 09377 PRINT_ERROR("Stop surface %d is not of same modeling engine as other input geometry.\n", 09378 stop_surf->id() ); 09379 return CUBIT_FAILURE; 09380 } 09381 09382 stop_surface = stop_surf->get_surface_ptr(); 09383 } 09384 09385 Curve *curve_to_sweep_along = NULL; 09386 if( edge_to_sweep_along ) 09387 { 09388 GeometryModifyEngine *tmp_gme = get_engine(edge_to_sweep_along); 09389 09390 if( gme != tmp_gme ) 09391 { 09392 PRINT_ERROR("Curve %d does is not of same modeling as other input geometry.\n", 09393 edge_to_sweep_along->id() ); 09394 return CUBIT_FAILURE; 09395 } 09396 09397 curve_to_sweep_along = edge_to_sweep_along->get_curve_ptr(); 09398 } 09399 09400 DLIList<int> merged_surface_ids; 09401 DLIList<int> merged_curve_ids; 09402 DLIList<BodySM*> neighbor_imprint_list; 09403 DLIList<Body*> bodies_to_modify; 09404 09405 if (!preview) 09406 { 09407 if( CubitUndo::get_undo_enabled() ) 09408 { 09409 DLIList<Body*> bodies_to_save; 09410 bodies_to_save += webcut_body_list; 09411 bodies_to_save += neighboring_bodies; 09412 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 09413 } 09414 09415 int i; 09416 for( i=neighboring_bodies.size(); i--; ) 09417 { 09418 Body *neighbor_body = neighboring_bodies.get_and_step(); 09419 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 09420 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 09421 09422 if( gme == neighbor_gme ) 09423 neighbor_imprint_list.append( tmp_body ); 09424 } 09425 09426 do_attribute_setup(); 09427 DLIList<BodySM*> bodies_sm_to_modify; 09428 bodies_sm_to_modify += body_sm_list; 09429 bodies_sm_to_modify += neighbor_imprint_list; 09430 push_attributes_before_modify( bodies_sm_to_modify ); 09431 bodies_to_modify += webcut_body_list; 09432 bodies_to_modify += neighboring_bodies; 09433 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 09434 } 09435 09436 CubitVector tmp_sweep_vector = sweep_vector; 09437 //get model bbox info...will scale sweep vector by its diagonal 09438 //so that we go far enough 09439 if( through_all || stop_surf ) 09440 { 09441 CubitBox bounding_box = GeometryQueryTool::instance()->model_bounding_box(); 09442 tmp_sweep_vector.normalize(); 09443 tmp_sweep_vector*=(2*bounding_box.diagonal().length()); 09444 } 09445 09446 DLIList<GeometryEntity*> ref_ent_list; 09447 for(int i = 0; i < curves_to_sweep.size(); i++) 09448 ref_ent_list.append((GeometryEntity*)(curves_to_sweep.get_and_step())); 09449 DLIList<BodySM*> swept_bodies; 09450 CubitStatus stat; 09451 09452 if( curve_to_sweep_along ) 09453 { 09454 DLIList<Curve*> curves_to_sweep_along; 09455 curves_to_sweep_along.append(curve_to_sweep_along); 09456 stat = gme->sweep_along_curve(ref_ent_list, swept_bodies, 09457 curves_to_sweep_along,0.0,0,false,stop_surface); 09458 09459 if (!stat && swept_bodies.size() == 0) 09460 return stat; 09461 } 09462 09463 else 09464 { 09465 stat = gme->sweep_translational(ref_ent_list, swept_bodies, 09466 tmp_sweep_vector,0.0,0, false, false, stop_surface); 09467 09468 if (!stat && swept_bodies.size() == 0) 09469 return stat; 09470 } 09471 09472 //stitch faces together 09473 BodySM* cutting_tool_ptr = NULL; 09474 DLIList<BodySM*> cutting_tools; 09475 stat = gme->stitch(swept_bodies, cutting_tools, CUBIT_FALSE, 1E-6); 09476 09477 if(cutting_tools.size() > 1 || cutting_tools.size() == 0) 09478 { 09479 //delete all swept faces 09480 for(int i = 0; i < cutting_tools.size(); i++) 09481 gme->get_gqe()->delete_solid_model_entities(cutting_tools.get_and_step()) ; 09482 return CUBIT_FAILURE; 09483 } 09484 else 09485 { 09486 cutting_tool_ptr = cutting_tools.get(); 09487 stat = gme->webcut( body_sm_list, cutting_tool_ptr, neighbor_imprint_list, 09488 new_sms, imprint_type, preview ); 09489 09490 // Delete the BodySM that was created to be used as a tool 09491 gme->get_gqe()->delete_solid_model_entities(cutting_tool_ptr) ; 09492 } 09493 09494 if (!preview) 09495 { 09496 restore_vg_after_modify(new_sms, bodies_to_modify, gme); 09497 remove_pushed_attributes(new_sms, bodies_to_modify); 09498 stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies, 09499 &merged_surface_ids, &merged_curve_ids ); 09500 do_attribute_cleanup(); 09501 09502 if( CubitUndo::get_undo_enabled() ) 09503 { 09504 if( stat == CUBIT_SUCCESS ) 09505 CubitUndo::note_result_bodies( new_bodies ); 09506 else 09507 CubitUndo::remove_last_undo(); 09508 } 09509 } 09510 09511 return stat; 09512 } 09513 09514 CubitStatus GeometryModifyTool::webcut_with_sweep_surfaces( 09515 DLIList<Body*> &webcut_body_list, 09516 DLIList<RefFace*> &tool_faces, 09517 const CubitVector sweep_vector, 09518 bool sweep_perp, 09519 bool through_all, 09520 bool outward, 09521 bool up_to_next, 09522 RefFace* stop_surf, 09523 RefEdge* edge_to_sweep_along, 09524 DLIList<Body*> &new_bodies, 09525 DLIList<Body*> &neighboring_bodies, 09526 ImprintType imprint_type, 09527 CubitBoolean merge, 09528 CubitBoolean preview) 09529 { 09530 if (!okay_to_modify( webcut_body_list, "WEBCUT" )) 09531 return CUBIT_FAILURE; 09532 09533 GfxPreview::clear(); 09534 09535 DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms; 09536 GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list); 09537 DLIList<Surface*> surfaces_to_sweep; 09538 if (gme) 09539 { 09540 GeometryModifyEngine* surf_gme = common_modify_engine( tool_faces, surfaces_to_sweep ); 09541 if( gme != surf_gme ){ 09542 PRINT_ERROR("All geometry not from the same modeling engine.\n"); 09543 return CUBIT_FAILURE; 09544 } 09545 } 09546 else{ 09547 PRINT_ERROR("All volumes not from the same modeling engine.\n"); 09548 return CUBIT_FAILURE; 09549 } 09550 09551 Surface *stop_surface = NULL; 09552 if( stop_surf ) 09553 { 09554 GeometryModifyEngine *tmp_gme = get_engine(stop_surf); 09555 09556 if( gme != tmp_gme ) 09557 { 09558 PRINT_ERROR("Stop surface %d is not of same modeling engine as other input geometry.\n", 09559 stop_surf->id() ); 09560 return CUBIT_FAILURE; 09561 } 09562 09563 stop_surface = stop_surf->get_surface_ptr(); 09564 } 09565 09566 Curve *curve_to_sweep_along = NULL; 09567 if( edge_to_sweep_along ) 09568 { 09569 GeometryModifyEngine *tmp_gme = get_engine(edge_to_sweep_along); 09570 09571 if( gme != tmp_gme ) 09572 { 09573 PRINT_ERROR("Curve %d does is not of same modeling as other input geometry.\n", 09574 edge_to_sweep_along->id() ); 09575 return CUBIT_FAILURE; 09576 } 09577 09578 //make sure that the curve is not part of the surface(s) being swept 09579 DLIList<RefFace*> faces_of_edge; 09580 edge_to_sweep_along->ref_faces( faces_of_edge ); 09581 09582 int kk; 09583 for( kk=faces_of_edge.size(); kk--; ) 09584 { 09585 if( tool_faces.is_in_list( faces_of_edge.get_and_step() ) ) 09586 { 09587 faces_of_edge.back(); 09588 PRINT_ERROR("Cannot perform sweep. Curve %d is in Surface %d\n", 09589 edge_to_sweep_along->id(), faces_of_edge.get()->id() ); 09590 return CUBIT_FAILURE; 09591 } 09592 } 09593 09594 curve_to_sweep_along = edge_to_sweep_along->get_curve_ptr(); 09595 } 09596 09597 DLIList<BodySM*> neighbor_imprint_list; 09598 DLIList<int> merged_surface_ids; 09599 DLIList<int> merged_curve_ids; 09600 DLIList<Body*> bodies_to_modify; 09601 09602 if (!preview) 09603 { 09604 if( CubitUndo::get_undo_enabled() ) 09605 { 09606 DLIList<Body*> bodies_to_save; 09607 bodies_to_save += webcut_body_list; 09608 bodies_to_save += neighboring_bodies; 09609 CubitUndo::save_state_with_cubit_file( bodies_to_save ); 09610 } 09611 09612 int i; 09613 for( i=neighboring_bodies.size(); i--; ) 09614 { 09615 Body *neighbor_body = neighboring_bodies.get_and_step(); 09616 BodySM *tmp_body = neighbor_body->get_body_sm_ptr(); 09617 GeometryModifyEngine *neighbor_gme = get_engine( tmp_body ); 09618 09619 if( gme == neighbor_gme ) 09620 neighbor_imprint_list.append( tmp_body ); 09621 } 09622 09623 do_attribute_setup(); 09624 DLIList<BodySM*> bodies_sm_to_modify; 09625 bodies_sm_to_modify += body_sm_list; 09626 bodies_sm_to_modify += neighbor_imprint_list; 09627 push_attributes_before_modify( bodies_sm_to_modify ); 09628 bodies_to_modify += webcut_body_list; 09629 bodies_to_modify += neighboring_bodies; 09630 get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids ); 09631 } 09632 09633 BodySM* cutting_tool_ptr = NULL; 09634 CubitStatus stat = prepare_surface_sweep( 09635 body_sm_list, surfaces_to_sweep, sweep_vector, sweep_perp, through_all, outward, 09636 up_to_next, stop_surface, curve_to_sweep_along, cutting_tool_ptr ); 09637 if (stat == CUBIT_SUCCESS) 09638 { 09639 stat = gme->webcut( body_sm_list, cutting_tool_ptr, neighbor_imprint_list, 09640 new_sms, imprint_type, preview ); 09641 09642 // Delete the BodySM that was created to be used as a tool 09643 gme->get_gqe()->delete_solid_model_entities(cutting_tool_ptr) ; 09644 } 09645 09646 if (!preview) 09647 { 09648 restore_vg_after_modify(new_sms, bodies_to_modify, gme); 09649 remove_pushed_attributes(new_sms, bodies_to_modify); 09650 stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies, 09651 &merged_surface_ids, &merged_curve_ids ); 09652 do_attribute_cleanup(); 09653 09654 if( CubitUndo::get_undo_enabled() ) 09655 { 09656 if( stat == CUBIT_SUCCESS ) 09657 CubitUndo::note_result_bodies( new_bodies ); 09658 else 09659 CubitUndo::remove_last_undo(); 09660 } 09661 } 09662 09663 return stat; 09664 } 09665 09666 CubitStatus GeometryModifyTool::split_free_curve(RefEdge *ref_edge, 09667 DLIList<CubitVector> &split_locations, 09668 DLIList<RefEdge*> &new_ref_edges ) 09669 { 09670 TopologyBridge* bridge = 0; 09671 GeometryModifyEngine* gme_ptr = get_engine(ref_edge, &bridge); 09672 Curve *curve = dynamic_cast<Curve*>(bridge); 09673 09674 if( CubitUndo::get_undo_enabled() ) 09675 { 09676 DLIList<RefEdge*> tmp_ents(1); 09677 tmp_ents.append( ref_edge ); 09678 CubitUndo::save_state_with_cubit_file( tmp_ents ); 09679 } 09680 09681 DLIList<Curve*> new_curves; 09682 if(split_locations.size() == 1) 09683 gme_ptr->split_curve(curve, (split_locations.get()), new_curves); 09684 else 09685 gme_ptr->split_free_curve( curve, split_locations, new_curves ); 09686 09687 if (!new_curves.size()) 09688 { 09689 if( CubitUndo::get_undo_enabled() ) 09690 CubitUndo::remove_last_undo(); 09691 return CUBIT_FAILURE; 09692 } 09693 09694 GeometryQueryTool::instance()->delete_RefEdge( ref_edge ); 09695 09696 int i; 09697 for( i=0; i<new_curves.size(); i++ ) 09698 { 09699 Curve *new_curve = new_curves.get_and_step(); 09700 RefEdge* new_edge = GeometryQueryTool::instance()->make_free_RefEdge(new_curve); 09701 if(new_edge) 09702 new_ref_edges.append(new_edge); 09703 if( CubitUndo::get_undo_enabled() ) 09704 CubitUndo::note_result_entity( new_edge ); 09705 } 09706 09707 return CUBIT_SUCCESS; 09708 } 09709 09710 //------------------------------------------------------------------------- 09711 // Purpose : split a multiple volume body into several bodies 09712 // each containing a single volume. 09713 // 09714 // Special Notes : 09715 // 09716 // Creator : David White 09717 // 09718 // Creation Date : 09/26/97 09719 //------------------------------------------------------------------------- 09720 CubitStatus GeometryModifyTool::split_body( Body *body_ptr, 09721 DLIList<Body*> &new_bodies ) const 09722 { 09723 int i; 09724 DLIList<RefVolume*> ref_vols; 09725 body_ptr->ref_volumes(ref_vols); 09726 if ( ref_vols.size() < 2 ) 09727 { 09728 //no need to split... 09729 new_bodies.append(body_ptr); 09730 return CUBIT_SUCCESS; 09731 } 09732 09733 DLIList<Body*> b_list; 09734 b_list.append(body_ptr); 09735 if (!okay_to_modify( b_list, "SPLIT" )) 09736 return CUBIT_FAILURE; 09737 09738 // Call the owning GeometryModifyEngine to split the body 09739 // so that there is one volume per body. 09740 BodySM* bodysm_ptr = body_ptr->get_body_sm_ptr(); 09741 GeometryModifyEngine* engine_ptr = get_engine(bodysm_ptr); 09742 if (!engine_ptr) { 09743 PRINT_ERROR("There is no modify engine available for this volume." 09744 " Volume cannot be split.\n"); 09745 return CUBIT_FAILURE; 09746 } 09747 09748 if( CubitUndo::get_undo_enabled() ) 09749 { 09750 DLIList<Body*> bodies(1); 09751 bodies.append( body_ptr ); 09752 CubitUndo::save_state_with_cubit_file( bodies ); 09753 } 09754 09755 DLIList<BodySM*> new_sm_list; 09756 CubitStatus stat = engine_ptr->split_body( bodysm_ptr, new_sm_list ); 09757 if ( new_sm_list.size() == 0 ) 09758 { 09759 PRINT_ERROR("failed in splitting volumes, orginal was lost.\n"); 09760 GeometryQueryTool::instance()->destroy_dead_entity(body_ptr); 09761 return CUBIT_FAILURE; 09762 } 09763 09764 bodysm_ptr = body_ptr->get_body_sm_ptr(); 09765 if (bodysm_ptr) 09766 { 09767 remove_dead_entity_names(body_ptr); 09768 body_ptr = GeometryQueryTool::instance()->make_Body(bodysm_ptr); 09769 } 09770 else 09771 { 09772 GeometryQueryTool::instance()->destroy_dead_entity(body_ptr); 09773 } 09774 09775 new_sm_list.reset(); 09776 for (i = new_sm_list.size(); i--; ) 09777 { 09778 bodysm_ptr = new_sm_list.get_and_step(); 09779 Body* body = GeometryQueryTool::instance()->make_Body(bodysm_ptr); 09780 new_bodies.append(body); 09781 } 09782 09783 if ( !GeometryModifyTool::instance()->get_new_ids()) 09784 { 09785 //Now reuse the body ids. 09786 DLIList<RefVolume*> new_ref_vols; 09787 for ( int ii = new_bodies.size(); ii > 0; ii-- ) 09788 { 09789 Body *temp_body = new_bodies.get_and_step(); 09790 new_ref_vols.clean_out(); 09791 temp_body->ref_volumes(new_ref_vols); 09792 int vol_id = new_ref_vols.get()->id(); 09793 if ( temp_body->id() != vol_id ) 09794 { 09795 //Check to see if this id is being used by 09796 //some other body. 09797 if ( RefEntityFactory::instance()->get_body(vol_id) == NULL ) 09798 { 09799 temp_body->set_id(vol_id); 09800 } 09801 //if it is in use, then we shouldn't mess around with it... 09802 } 09803 } 09804 } 09805 09806 if( CubitUndo::get_undo_enabled() ) 09807 CubitUndo::note_result_bodies( new_bodies ); 09808 09809 GeometryQueryTool::instance()->cleanout_deactivated_geometry(); 09810 return stat; 09811 } 09812 09813 //------------------------------------------------------------------------- 09814 // Purpose : Separate surfaces from a sheet body into separate bodies. 09815 // Connected surfaces will remain united but be placed in 09816 // a new body. 09817 // 09818 // Special Notes : 09819 // 09820 // Creator : Steve Storm 09821 // 09822 // Creation Date : 02/23/2008 09823 //------------------------------------------------------------------------- 09824 CubitStatus 09825 GeometryModifyTool::separate_surfaces( DLIList<RefFace*> &ref_face_list, 09826 DLIList<Body*> &new_bodies ) 09827 { 09828 int i; 09829 RefFace *ref_face_ptr; 09830 09831 for( i=ref_face_list.size(); i--; ) 09832 { 09833 ref_face_ptr = ref_face_list.get(); 09834 09835 // Check for no body 09836 DLIList<Body*> body_list; 09837 ref_face_ptr->bodies( body_list ); 09838 if( body_list.size()==0 ) 09839 { 09840 PRINT_ERROR( "Surface %d is not contained within a parent body.\n" 09841 " It cannot be separated.\n", ref_face_ptr->id() ); 09842 return CUBIT_FAILURE; 09843 } 09844 } 09845 09846 // Check for virtual geometry 09847 DLIList<RefEntity*> ref_ent_list; 09848 CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list); 09849 if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) ) 09850 { 09851 PRINT_ERROR("SEPARATING surfaces containing virtual geometry is not\n" 09852 " allowed. Delete virtual geometry on these surfaces\n" 09853 " before operation.\n" ); 09854 return CUBIT_FAILURE; 09855 } 09856 09857 // Prep for undo 09858 DLIList<Body*> body_list; 09859 for( i=ref_face_list.size(); i--; ) 09860 ref_face_list.get_and_step()->bodies( body_list ); 09861 body_list.uniquify_ordered(); 09862 09863 if( CubitUndo::get_undo_enabled() ) 09864 CubitUndo::save_state_with_cubit_file( body_list ); 09865 09866 // Handle surfaces from different modify engines. Copy the input list since 09867 // we will be pulling RefFaces out of it. 09868 DLIList<RefFace*> copied_ref_face_list = ref_face_list; 09869 09870 // Keep track of errors and success 09871 int error_occurred = 0; 09872 int successful_case = 0; 09873 09874 GeometryModifyEngine *gme_ptr; 09875 while( copied_ref_face_list.size() ) 09876 { 09877 // Need to send in Surfaces 09878 DLIList<Surface*> surface_list; 09879 DLIList<RefFace*> gme_face_list; 09880 09881 gme_ptr = pull_common_surfs( copied_ref_face_list, gme_face_list, 09882 surface_list ); 09883 if( !gme_ptr ) 09884 return CUBIT_FAILURE; 09885 09886 // Get the owning bodies of the faces...needed for finish_sm_op 09887 DLIList<Body*> gme_body_list; 09888 for( i=gme_face_list.size(); i--; ) 09889 gme_face_list.get_and_step()->bodies( gme_body_list ); 09890 gme_body_list.uniquify_ordered(); 09891 09892 DLIList<BodySM*> new_sm_list; 09893 DLIList<Body*> new_body_list; 09894 if( gme_ptr->separate_surfaces( surface_list, new_sm_list ) == CUBIT_FAILURE || 09895 finish_sm_op(gme_body_list, new_sm_list, new_body_list ) == CUBIT_FAILURE ) 09896 { 09897 error_occurred++; 09898 continue; 09899 } 09900 09901 new_bodies += new_body_list; 09902 successful_case++; 09903 } 09904 09905 if( error_occurred && !successful_case ) 09906 return CUBIT_FAILURE; 09907 09908 // Following is copied from split_body - to keep same behavior. When all 09909 // surfaces are separated from a given body, separate_surfaces just separates 09910 // the body. Without the code below we get new body ids. 09911 if ( !GeometryModifyTool::instance()->get_new_ids()) 09912 { 09913 //Now reuse the body ids. 09914 DLIList<RefVolume*> new_ref_vols; 09915 for ( int ii = new_bodies.size(); ii > 0; ii-- ) 09916 { 09917 Body *temp_body = new_bodies.get_and_step(); 09918 new_ref_vols.clean_out(); 09919 temp_body->ref_volumes(new_ref_vols); 09920 int vol_id = new_ref_vols.get()->id(); 09921 if ( temp_body->id() != vol_id ) 09922 { 09923 //Check to see if this id is being used by 09924 //some other body. 09925 if ( RefEntityFactory::instance()->get_body(vol_id) == NULL ) 09926 { 09927 temp_body->set_id(vol_id); 09928 } 09929 //if it is in use, then we shouldn't mess around with it... 09930 } 09931 } 09932 } 09933 09934 if( CubitUndo::get_undo_enabled() ) 09935 CubitUndo::note_result_bodies( new_bodies ); 09936 09937 return CUBIT_SUCCESS; 09938 } 09939 09940 //------------------------------------------------------------------------- 09941 // Purpose : Reverse a body 09942 // 09943 // Special Notes : Moved from Body 09944 // 09945 // Creator : Jason Kraftcheck 09946 // 09947 // Creation Date : 09948 //------------------------------------------------------------------------- 09949 CubitStatus GeometryModifyTool::reverse( DLIList<Body*> &body_list ) 09950 { 09951 DLIList<Body*> reversed_bodies; 09952 int i; 09953 for( i=body_list.size(); i--; ) 09954 { 09955 Body *body = body_list.get_and_step(); 09956 BodySM* body_sm = body->get_body_sm_ptr(); 09957 GeometryModifyEngine* gme = get_engine( body_sm ); 09958 if (!gme) { 09959 PRINT_ERROR("Body %d does not have a modify engine.\n", body->id()); 09960 continue; 09961 } 09962 09963 CubitStatus stat = gme->reverse_body( body_sm ); 09964 09965 if ( CUBIT_SUCCESS != stat ) 09966 { 09967 PRINT_ERROR("Reverse failed.\n"); 09968 continue; 09969 } 09970 else 09971 { 09972 reversed_bodies.append( body ); 09973 GeometryQueryTool::instance()->make_Body( body_sm ); 09974 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, body)); 09975 PRINT_INFO("Reversed body %d.\n", body->id()); 09976 continue; 09977 } 09978 } 09979 09980 if( CubitUndo::get_undo_enabled() ) 09981 { 09982 CubitString undo_command("reverse body "); 09983 for( i=reversed_bodies.size(); i--; ) 09984 { 09985 undo_command += CubitString::number(reversed_bodies.get_and_step()->id()); 09986 undo_command += " "; 09987 } 09988 CubitUndo::set_undo_by_command( undo_command ); 09989 } 09990 09991 return CUBIT_SUCCESS; 09992 } 09993 09994 //=============================================================================== 09995 // Function : reverse 09996 // Member Type: PUBLIC 09997 // Description: Reverse given surfaces (flip normals) 09998 // Author : Steve Storm (CAT) 09999 // Date : 4/3/2007 10000 //=============================================================================== 10001 CubitStatus GeometryModifyTool::reverse( DLIList<RefFace*> &ref_face_list ) 10002 { 10003 // Check for virtual geometry 10004 DLIList<RefEntity*> ref_ent_list; 10005 CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list); 10006 if( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) ) 10007 { 10008 PRINT_ERROR("REVERSING surfaces containing virtual geometry is not\n" 10009 " allowed. Delete virtual geometry on surfaces before\n" 10010 " operation.\n" ); 10011 return CUBIT_FAILURE; 10012 } 10013 10014 // Get the owning bodies of the faces 10015 int i; 10016 DLIList<Body*> body_list; 10017 for( i=ref_face_list.size(); i--; ) 10018 ref_face_list.get_and_step()->bodies( body_list ); 10019 body_list.uniquify_ordered(); 10020 10021 // Handle surfaces from different modify engines. Copy the input list since 10022 // we will be pulling RefFaces out of it. 10023 DLIList<RefFace*> copied_ref_face_list = ref_face_list; 10024 10025 // Keep track of overall errors and successes 10026 int error_occurred = 0; 10027 int successful_case = 0; 10028 GeometryModifyEngine *gme_ptr; 10029 10030 while( copied_ref_face_list.size() ) 10031 { 10032 // Need to send in Surfaces 10033 DLIList<Surface*> surface_list; 10034 DLIList<RefFace*> common_face_list; 10035 10036 gme_ptr = pull_common_surfs( copied_ref_face_list, common_face_list, 10037 surface_list ); 10038 if( !gme_ptr ) 10039 return CUBIT_FAILURE; 10040 10041 if( gme_ptr->flip_normals( surface_list ) == CUBIT_FAILURE ) 10042 error_occurred = 1; 10043 else 10044 successful_case = 1; 10045 } 10046 10047 if( error_occurred && !successful_case ) 10048 return CUBIT_FAILURE; 10049 10050 // Update the impacted bodies 10051 Body *body_ptr; 10052 BodySM* body_sm_ptr; 10053 DLIList<BodySM*> new_sm_list; 10054 for( i=body_list.size(); i--; ) 10055 { 10056 body_ptr = body_list.get_and_step(); 10057 body_sm_ptr = body_ptr->get_body_sm_ptr(); 10058 new_sm_list.append( body_sm_ptr ); 10059 } 10060 10061 DLIList<Body*> new_body_list; 10062 CubitStatus status = finish_sm_op(body_list, new_sm_list, new_body_list ); 10063 10064 if( CUBIT_FAILURE == status ) 10065 return CUBIT_FAILURE; 10066 10067 for( int k=0; k< ref_face_list.size(); k++ ) 10068 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, ref_face_list.get_and_step() )); 10069 10070 return CUBIT_SUCCESS; 10071 } 10072 10073 //------------------------------------------------------------------------- 10074 // Purpose : split a periodic surface. 10075 // 10076 // Special Notes : 10077 // 10078 // Creator : David White 10079 // 10080 // Creation Date : 09/26/97 10081 //------------------------------------------------------------------------- 10082 10083 CubitStatus GeometryModifyTool::split_periodic(Body *body_ptr, 10084 Body *&new_body_ptr ) 10085 { 10086 DLIList<Body*> b_list(1); 10087 b_list.append(body_ptr); 10088 if (!okay_to_modify( b_list, "SPLIT" )) 10089 return CUBIT_FAILURE; 10090 10091 BodySM* body_sm = body_ptr->get_body_sm_ptr(); 10092 GeometryModifyEngine* gme = get_engine(body_sm); 10093 if (!gme) { 10094 PRINT_ERROR("Volume %d does not have a modify engine.\n", body_ptr->id()); 10095 return CUBIT_FAILURE; 10096 } 10097 10098 BodySM* new_sm = 0; 10099 10100 if (CubitUndo::get_undo_enabled()) 10101 CubitUndo::save_state_with_cubit_file(b_list); 10102 10103 DLIList<BodySM*> body_sms; 10104 body_sms.append(body_sm); 10105 10106 do_attribute_setup(); 10107 push_attributes_before_modify(body_sms); 10108 10109 // Call the default GeometryModifyEngine to create a new TBPoint 10110 CubitStatus stat = gme->split_periodic( body_sm, new_sm ); 10111 10112 DLIList<BodySM*> new_bodysm_list; 10113 if(new_sm) 10114 new_bodysm_list.append(new_sm); 10115 DLIList<Body*> old_body_list; 10116 old_body_list.append(body_ptr); 10117 restore_vg_after_modify(new_bodysm_list, old_body_list, gme); 10118 remove_pushed_attributes(new_bodysm_list, old_body_list); 10119 do_attribute_cleanup(); 10120 10121 update_body(body_ptr); 10122 10123 new_body_ptr = 0; 10124 if (new_sm) 10125 new_body_ptr = GeometryQueryTool::instance()->make_Body(new_sm); 10126 10127 if (new_body_ptr) 10128 { 10129 if (CubitUndo::get_undo_enabled()) 10130 CubitUndo::note_result_body(new_body_ptr); 10131 } 10132 else 10133 { 10134 if (CubitUndo::get_undo_enabled()) 10135 CubitUndo::remove_last_undo(); 10136 } 10137 10138 GeometryQueryTool::instance()->cleanout_deactivated_geometry(); 10139 10140 return stat; 10141 } 10142 10143 //=============================================================================== 10144 // Function : split_surface 10145 // Member Type: PUBLIC 10146 // Description: Split a single surface into one or more pieces 10147 // Author : Steve Storm (CAT) 10148 // Date : 07/04 10149 //=============================================================================== 10150 CubitStatus 10151 GeometryModifyTool::split_surface( RefFace *ref_face_ptr, 10152 DLIList<CubitVector*> &locations, 10153 DLIList<DLIList<CubitVector*>*> &vec_lists, 10154 CubitBoolean preview_flg, 10155 CubitBoolean create_ref_edges_flg, 10156 CubitBoolean clear_previous_previews ) 10157 { 10158 // Check for virtual geometry 10159 DLIList<RefFace*> ref_face_list; 10160 ref_face_list.append( ref_face_ptr ); 10161 10162 DLIList<Body*> b_list; 10163 Body* body = ref_face_ptr->body(); 10164 if (body) 10165 b_list.append(body); 10166 else 10167 { 10168 PRINT_ERROR( "Surface %d is not contained within a parent body.\n" 10169 " It cannot be split.\n", ref_face_ptr->id() ); 10170 return CUBIT_FAILURE; 10171 } 10172 10173 if (!okay_to_modify( b_list, "SPLIT_SURFACE" )) 10174 return CUBIT_FAILURE; 10175 10176 int i; 10177 DLIList<Body*> old_body_list; 10178 for( i=ref_face_list.size(); i--; ) 10179 { 10180 ref_face_ptr = ref_face_list.get_and_step(); 10181 10182 DLIList<Body*> body_list; 10183 ref_face_ptr->bodies( body_list ); 10184 old_body_list.merge_unique( body_list ); 10185 } 10186 10187 //bad geom with no body -- dont try to imprint this... 10188 //quick and dirty fix by (aga@cat|1/7/04) 10189 if( old_body_list.size() < 1 ) 10190 { 10191 PRINT_ERROR( "Surface %d is not contained within a parent body\n." 10192 " It cannot be split.\n", ref_face_ptr->id() ); 10193 return CUBIT_FAILURE; 10194 } 10195 10196 SplitSurfaceTool sst; 10197 if( preview_flg == CUBIT_TRUE ) 10198 return sst.preview( ref_face_ptr, locations, vec_lists, create_ref_edges_flg, 10199 clear_previous_previews ); 10200 else 10201 return sst.split_surface( ref_face_ptr, vec_lists ); 10202 } 10203 10204 //=============================================================================== 10205 // Function : split_surface 10206 // Member Type: PUBLIC 10207 // Description: Split multiple surfaces 10208 // Author : Greg Schebler (CAT) 10209 // Date : 06/08 10210 //=============================================================================== 10211 10212 CubitStatus 10213 GeometryModifyTool::split_surface( DLIList<RefFace*> &ref_face_list, 10214 DLIList<CubitVector*> &locations, 10215 DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists, 10216 CubitBoolean preview_flg, 10217 CubitBoolean create_ref_edges_flg, 10218 CubitBoolean clear_previous_previews ) 10219 { 10220 // Check for virtual geometry 10221 DLIList<Body*> b_list; 10222 int gg; 10223 for( gg = ref_face_list.size() ; gg > 0 ; gg--) 10224 { 10225 RefFace* ref_face_ptr = ref_face_list.get_and_step(); 10226 Body* body = ref_face_ptr->body(); 10227 if (body) 10228 b_list.append(body); 10229 else 10230 { 10231 PRINT_ERROR( "Surface %d is not contained within a parent body.\n" 10232 " It cannot be split.\n", ref_face_ptr->id() ); 10233 return CUBIT_FAILURE; 10234 } 10235 } 10236 if (!okay_to_modify( b_list, "SPLIT_SURFACE" )) 10237 return CUBIT_FAILURE; 10238 10239 int ii; 10240 10241 for( ii = ref_face_list.size(); ii > 0 ; ii--) 10242 { 10243 DLIList<Body*> old_body_list; 10244 RefFace* ref_face_ptr = ref_face_list.get_and_step(); 10245 10246 DLIList<Body*> body_list; 10247 ref_face_ptr->bodies( body_list ); 10248 old_body_list.merge_unique( body_list ); 10249 10250 if( old_body_list.size() < 1 ) 10251 { 10252 PRINT_ERROR( "Surface %d is not contained within a parent body\n." 10253 " It cannot be split.\n", ref_face_ptr->id() ); 10254 return CUBIT_FAILURE; 10255 } 10256 } 10257 10258 SplitSurfaceTool sst; 10259 if( preview_flg == CUBIT_TRUE ) 10260 return sst.preview( ref_face_list, locations, list_of_vec_lists, create_ref_edges_flg, 10261 clear_previous_previews ); 10262 else 10263 return sst.split_surface( ref_face_list, list_of_vec_lists ); 10264 } 10265 10266 //=============================================================================== 10267 // Function : split_surfaces_extend 10268 // Member Type: PUBLIC 10269 // Description: Split surfaces by extending hardline curves on the surface 10270 // Author : Steve Storm (CAT) 10271 // Date : 10/07 10272 //=============================================================================== 10273 CubitStatus 10274 GeometryModifyTool::split_surfaces_extend( DLIList<RefFace*> &ref_face_list, 10275 DLIList<RefVertex*> &ref_vertex_list, 10276 CubitBoolean preview_flg, 10277 CubitBoolean create_ref_edges_flg ) 10278 { 10279 int i; 10280 RefFace *ref_face_ptr; 10281 10282 for( i=ref_face_list.size(); i--; ) 10283 { 10284 ref_face_ptr = ref_face_list.get(); 10285 10286 // Check for no body 10287 DLIList<Body*> body_list; 10288 ref_face_ptr->bodies( body_list ); 10289 if( body_list.size()==0 ) 10290 { 10291 PRINT_ERROR( "Surface %d is not contained within a parent body.\n" 10292 " It cannot be split.\n", ref_face_ptr->id() ); 10293 return CUBIT_FAILURE; 10294 } 10295 } 10296 10297 // Check for virtual geometry 10298 DLIList<RefEntity*> ref_ent_list; 10299 CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list); 10300 if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) ) 10301 { 10302 PRINT_ERROR("SPLITTING surfaces containing virtual geometry is not\n" 10303 " allowed. Delete virtual geometry on these surfaces\n" 10304 " before operation.\n" ); 10305 return CUBIT_FAILURE; 10306 } 10307 10308 // Make sure all surfaces are from same geometry engine 10309 if ( !same_modify_engine(ref_ent_list, CUBIT_TRUE) ) 10310 { 10311 PRINT_ERROR("Performing SPLIT with surfaces containing geometry from\n" 10312 "different modeling engines is not allowed.\n" 10313 "Delete uncommon geometry on these surfaces before operation.\n\n"); 10314 return CUBIT_FAILURE; 10315 } 10316 10317 SplitSurfaceTool sst; 10318 return sst.split_surfaces_extend( ref_face_list, ref_vertex_list, 10319 preview_flg, create_ref_edges_flg ); 10320 } 10321 10322 //=============================================================================== 10323 // Function : split_surfaces 10324 // Member Type: PUBLIC 10325 // Description: Split a chain of surfaces into one or more pieces 10326 // Author : Steve Storm (CAT) 10327 // Date : 01/04 10328 //=============================================================================== 10329 CubitStatus 10330 GeometryModifyTool::split_surfaces( DLIList<RefFace*> &ref_face_list, 10331 int num_segs, 10332 double fraction, 10333 double distance, 10334 RefEdge *from_curve_ptr, 10335 DLIList<RefVertex*> &corner_vertex_list, 10336 DLIList<RefVertex*> &through_vertex_list, 10337 RefEdge *curve_dir_ptr, 10338 CubitBoolean preview_flg, 10339 CubitBoolean create_ref_edges_flg ) 10340 { 10341 // Get parent bodies - all surfs must be from same body 10342 int i; 10343 DLIList<Body*> old_body_list; 10344 RefFace *ref_face_ptr; 10345 ref_face_list.reset(); 10346 for( i=ref_face_list.size(); i--; ) 10347 { 10348 ref_face_ptr = ref_face_list.get_and_step(); 10349 10350 DLIList<Body*> body_list; 10351 ref_face_ptr->bodies( body_list ); 10352 old_body_list.merge_unique( body_list ); 10353 } 10354 10355 if( old_body_list.size() > 1 ) 10356 { 10357 PRINT_ERROR( "This operation requires all surfaces to be from the same volume\n" ); 10358 // Note: this restriction could be pretty easily lifted by sorting the 10359 // input lists and calling the SplitSurfaceTool separately for each set of 10360 // surfaces on each body. 10361 return CUBIT_FAILURE; 10362 } 10363 10364 //bad geom with no body -- dont try to imprint this... 10365 //quick and dirty fix by (aga@cat|1/7/04) 10366 if( old_body_list.size() < 1 ) 10367 { 10368 PRINT_ERROR( "A surface is not contained within a parent body.\n" 10369 " It cannot be split.\n"); 10370 return CUBIT_FAILURE; 10371 } 10372 10373 // Check for virtual geometry 10374 DLIList<RefEntity*> ref_ent_list; 10375 CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list); 10376 if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) ) 10377 { 10378 PRINT_ERROR("SPLITTING surfaces containing virtual geometry is not\n" 10379 " allowed. Delete virtual geometry on these surfaces\n" 10380 " before operation.\n" ); 10381 return CUBIT_FAILURE; 10382 } 10383 10384 // Make sure all surfaces are from same geometry engine 10385 if ( !same_modify_engine(ref_ent_list, CUBIT_TRUE) ) 10386 { 10387 PRINT_ERROR("Performing SPLIT with surfaces containing geometry from\n" 10388 "different modeling engines is not allowed.\n" 10389 "Delete uncommon geometry on these surfaces before operation.\n\n"); 10390 return CUBIT_FAILURE; 10391 } 10392 10393 SplitSurfaceTool split_tool; 10394 return split_tool.split_surfaces( ref_face_list, num_segs, fraction, 10395 distance, from_curve_ptr, corner_vertex_list, through_vertex_list, 10396 curve_dir_ptr, preview_flg, create_ref_edges_flg ); 10397 } 10398 10399 //=============================================================================== 10400 // Function : split_surfaces_offset 10401 // Member Type: PUBLIC 10402 // Description: Split a list of surface offset from a curve 10403 // Author : Sam Showman (CAT) 10404 // Date : 05/05 10405 //=============================================================================== 10406 CubitStatus 10407 GeometryModifyTool::split_surfaces_offset(DLIList<RefFace*> &ref_face_list, 10408 DLIList<RefEdge*> &edge_list, 10409 int num_segs, 10410 double distance, 10411 CubitBoolean partition_flg, 10412 CubitBoolean blunt_flg, 10413 CubitBoolean preview_flg, 10414 CubitBoolean create_ref_edges_flg) 10415 { 10416 int i; 10417 DLIList<Body*> old_body_list; 10418 RefFace *ref_face_ptr; 10419 ref_face_list.reset(); 10420 for( i=ref_face_list.size(); i--; ) 10421 { 10422 ref_face_ptr = ref_face_list.get_and_step(); 10423 10424 DLIList<Body*> body_list; 10425 ref_face_ptr->bodies( body_list ); 10426 old_body_list.merge_unique( body_list ); 10427 } 10428 10429 //check for geometry with no body 10430 if( old_body_list.size() < 1 ) 10431 { 10432 PRINT_ERROR( "A surface is not contained within a parent body.\n" 10433 " It cannot be split.\n"); 10434 return CUBIT_FAILURE; 10435 } 10436 10437 // Check for virtual geometry 10438 DLIList<RefEntity*> ref_ent_list; 10439 CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list); 10440 if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) ) 10441 { 10442 PRINT_ERROR("SPLITTING surfaces containing virtual geometry is not\n" 10443 " allowed. Delete virtual geometry on these surfaces\n" 10444 " before operation.\n" ); 10445 return CUBIT_FAILURE; 10446 } 10447 10448 // Make sure all surfaces are from same geometry engine 10449 // Make sure all curves are from same geometry engine 10450 CAST_LIST_TO_PARENT(edge_list, ref_ent_list); 10451 if ( !same_modify_engine(ref_ent_list, CUBIT_TRUE) ) 10452 { 10453 PRINT_ERROR("Performing SPLIT with geometry from\n" 10454 "different modeling engines is not allowed.\n"); 10455 return CUBIT_FAILURE; 10456 } 10457 10458 OffsetSplitTool split_tool; 10459 return split_tool.split_surfaces_offset( 10460 ref_face_list, 10461 edge_list, 10462 num_segs, 10463 distance, 10464 partition_flg, 10465 blunt_flg, 10466 preview_flg, 10467 create_ref_edges_flg); 10468 } 10469 10470 //=============================================================================== 10471 // Function : auto_mid_surface 10472 // Member Type: PUBLIC 10473 // Description: Automatically midsurface a volume 10474 // Author : Sam Showman (CAT) 10475 // Date : 12/07 10476 //=============================================================================== 10477 CubitStatus 10478 GeometryModifyTool::auto_mid_surface(DLIList<Body*> &body_list_in, 10479 DLIList<Body*> &body_list_out, 10480 DLIList<Body*> &old_bodies_midsurfaced, 10481 DLIList<double> &thickness_list, 10482 double lower_tol, 10483 double upper_tol, 10484 CubitBoolean delete_midsurfaced, 10485 10486 CubitBoolean preview) 10487 { 10488 // Check for virtual geometry 10489 DLIList<RefEntity*> ref_ent_list; 10490 CAST_LIST_TO_PARENT(body_list_in, ref_ent_list); 10491 if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) ) 10492 { 10493 PRINT_ERROR("Midsurfacing volumes containing virtual geometry is not\n" 10494 " allowed. Delete virtual geometry on these surfaces\n" 10495 " before operation.\n" ); 10496 return CUBIT_FAILURE; 10497 } 10498 10499 // Make sure all surfaces are from same geometry engine 10500 if ( !same_modify_engine(ref_ent_list, CUBIT_TRUE) ) 10501 { 10502 PRINT_ERROR("Performing Midsurface with geometry from\n" 10503 "different modeling engines is not allowed.\n"); 10504 return CUBIT_FAILURE; 10505 } 10506 10507 AutoMidsurfaceTool mid_tool; 10508 DLIList<BodySM*> bodysm_list_out; 10509 10510 if (CubitUndo::get_undo_enabled() && delete_midsurfaced && !preview) 10511 CubitUndo::save_state_with_cubit_file(body_list_in); 10512 10513 CubitStatus result = mid_tool.midsurface( 10514 body_list_in, 10515 bodysm_list_out, 10516 old_bodies_midsurfaced, 10517 thickness_list, 10518 lower_tol, 10519 upper_tol, 10520 delete_midsurfaced, 10521 preview); 10522 10523 10524 if (result == CUBIT_SUCCESS && 10525 bodysm_list_out.size() > 0 && 10526 !preview) 10527 { 10528 if(CubitUndo::get_undo_enabled()) 10529 CubitUndo::save_state(); 10530 10531 for( int i=0; i<bodysm_list_out.size(); i++ ) 10532 { 10533 body_list_out.append(GeometryQueryTool::instance()->make_Body(bodysm_list_out[i])); 10534 } 10535 10536 if( CubitUndo::get_undo_enabled() ) 10537 { 10538 if( body_list_out.size() ) 10539 CubitUndo::note_result_bodies( body_list_out ); 10540 else 10541 CubitUndo::remove_last_undo(); 10542 } 10543 } 10544 10545 return result; 10546 } 10547 10548 //------------------------------------------------------------------------- 10549 // Purpose : clean RefEntity 10550 // 10551 // Special Notes : 10552 // 10553 // Creator : Lingyun Pan (CAT) 10554 // 10555 // Creation Date : 07/15/01 10556 //------------------------------------------------------------------------- 10557 10558 CubitStatus 10559 GeometryModifyTool::regularize_refentity(RefEntity *old_entity_ptr, Body *&new_body_ptr) 10560 { 10561 BasicTopologyEntity* bte_ptr = dynamic_cast<BasicTopologyEntity*>(old_entity_ptr); 10562 if (!bte_ptr) 10563 { 10564 PRINT_ERROR("Invalid entity passed to regularize_refentity(..)\n"); 10565 return CUBIT_FAILURE; 10566 } 10567 10568 DLIList<Body*> body_list; 10569 bte_ptr->bodies(body_list); 10570 10571 //ignore free entities 10572 if( body_list.size() == 0 ) 10573 { 10574 PRINT_ERROR("%s %d is a free entity. Cannot regularize it.\n", old_entity_ptr->class_name(), 10575 old_entity_ptr->id() ); 10576 new_body_ptr = NULL; 10577 return CUBIT_FAILURE; 10578 } 10579 10580 if (!okay_to_modify( body_list, "REGULARIZE" )) 10581 return CUBIT_FAILURE; 10582 10583 DLIList<TopologyBridge*> bridge_list; 10584 // For curves we can try to handle composite curves. 10585 if(dynamic_cast<RefEdge*>(old_entity_ptr)) 10586 { 10587 TopologyBridge *first_bridge = bte_ptr->bridge_manager()->topology_bridge(); 10588 GeometryQueryEngine *gqe = first_bridge->get_geometry_query_engine(); 10589 gqe->get_underlying_bridges(first_bridge, bridge_list); 10590 if(bridge_list.size() == 0) 10591 bridge_list.append(first_bridge); 10592 } 10593 else 10594 { 10595 bte_ptr->bridge_manager()->get_bridge_list(bridge_list); 10596 } 10597 10598 //bte_ptr->bridge_manager()->get_bridge_list(bridge_list); 10599 bridge_list.reset(); 10600 10601 DLIList<BodySM*> new_sm_list; 10602 DLIList<Body*> new_body_list; 10603 CubitStatus stat = CUBIT_SUCCESS; 10604 10605 do_attribute_setup(); 10606 10607 GeometryModifyEngine *save_gme = NULL; 10608 for (int i = bridge_list.size(); i--; ) 10609 { 10610 TopologyBridge* bridge = bridge_list.get_and_step(); 10611 GeometryEntity* geom_ptr = dynamic_cast<GeometryEntity*>(bridge); 10612 GeometryModifyEngine* gme = get_engine(geom_ptr); 10613 if(!save_gme) 10614 save_gme = gme; 10615 if (!gme) continue; 10616 10617 DLIList<BodySM*> body_sm_list; 10618 geom_ptr->bodysms(body_sm_list); 10619 push_attributes_before_modify(body_sm_list); 10620 10621 BodySM *new_body_sm = NULL; 10622 if (!gme->regularize_entity( geom_ptr, new_body_sm )) 10623 stat = CUBIT_FAILURE; 10624 10625 if (new_body_sm) 10626 new_sm_list.append(new_body_sm); 10627 } 10628 10629 new_sm_list.uniquify_ordered(); 10630 10631 // This is bad in that it assumes all of the gmes will be the 10632 // same but I don't know that we truly support the other case 10633 // anyway. 10634 if(new_sm_list.size()) 10635 { 10636 restore_vg_after_modify(new_sm_list, body_list, save_gme); 10637 remove_pushed_attributes(new_sm_list, body_list); 10638 } 10639 10640 if (!finish_sm_op(body_list, new_sm_list, new_body_list)) 10641 stat = CUBIT_FAILURE; 10642 10643 do_attribute_cleanup(); 10644 10645 new_body_ptr = new_body_list.size() ? new_body_list.get() : 0; 10646 return stat; 10647 } 10648 10649 CubitStatus GeometryModifyTool::test_regularize_refentity(RefEntity *old_entity_ptr) 10650 { 10651 DLIList<RefEntity*> tmp_ref_ent_list(1); 10652 tmp_ref_ent_list.append( old_entity_ptr ); 10653 if( GeometryQueryTool::instance()->contains_intermediate_geometry(tmp_ref_ent_list) ) 10654 { 10655 return CUBIT_FAILURE; 10656 } 10657 10658 BasicTopologyEntity* bte_ptr = dynamic_cast<BasicTopologyEntity*>(old_entity_ptr); 10659 if (!bte_ptr) 10660 { 10661 return CUBIT_FAILURE; 10662 } 10663 10664 DLIList<TopologyBridge*> bridge_list; 10665 bte_ptr->bridge_manager()->get_bridge_list(bridge_list); 10666 bridge_list.reset(); 10667 10668 CubitStatus stat = CUBIT_SUCCESS; 10669 10670 for (int i = bridge_list.size(); i--; ) 10671 { 10672 TopologyBridge* bridge = bridge_list.get_and_step(); 10673 GeometryEntity* geom_ptr = dynamic_cast<GeometryEntity*>(bridge); 10674 GeometryModifyEngine* gme = get_engine(geom_ptr); 10675 if (!gme) continue; 10676 10677 if (!gme->test_regularize_entity( geom_ptr )) 10678 stat = CUBIT_FAILURE; 10679 } 10680 10681 return stat; 10682 } 10683 10684 //------------------------------------------------------------------------- 10685 // Purpose : split a multiple volume body into several bodies 10686 // each containing a single volume. 10687 // 10688 // Special Notes : 10689 // 10690 // Creator : David White 10691 // 10692 // Creation Date : 09/26/97 10693 //------------------------------------------------------------------------- 10694 10695 CubitStatus GeometryModifyTool::regularize_body(Body *body_ptr, 10696 Body *&new_body ) 10697 { 10698 DLIList<Body*> b_list; 10699 b_list.append(body_ptr); 10700 if (!okay_to_modify( b_list, "REGULARIZE" )) 10701 return CUBIT_FAILURE; 10702 10703 BodySM* body_sm = body_ptr->get_body_sm_ptr(), *new_sm = 0; 10704 GeometryModifyEngine* gme = get_engine(body_sm); 10705 if (!gme) { 10706 PRINT_ERROR("Volume does not have a modify engine.\n" ); 10707 return CUBIT_FAILURE; 10708 } 10709 10710 do_attribute_setup(); 10711 DLIList<BodySM*> body_sm_list, new_bodysm_list; 10712 body_sm_list.append(body_sm); 10713 push_attributes_before_modify(body_sm_list); 10714 10715 CubitStatus stat = gme->regularize_body( body_sm, new_sm ); 10716 if ( new_sm == NULL ) 10717 { 10718 PRINT_ERROR("REGULARIZATION failure.\n"); 10719 return CUBIT_FAILURE; 10720 } 10721 10722 // remove mesh from modified body 10723 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_ENTITY_MODIFIED, body_ptr)); 10724 10725 new_bodysm_list.append(new_sm); 10726 restore_vg_after_modify(new_bodysm_list, b_list, gme); 10727 remove_pushed_attributes(new_bodysm_list, b_list); 10728 10729 body_sm = body_ptr->get_body_sm_ptr(); 10730 update_body(body_ptr); 10731 10732 new_body = GeometryQueryTool::instance()->make_Body(new_sm); 10733 GeometryQueryTool::instance()->cleanout_deactivated_geometry(); 10734 10735 do_attribute_cleanup(); 10736 10737 return stat; 10738 } 10739 10740 CubitStatus 10741 GeometryModifyTool::create_solid_bodies_from_surfs( DLIList<RefFace*> &ref_face_list, 10742 DLIList<Body*> &new_bodies, 10743 CubitBoolean keep_old, 10744 CubitBoolean heal, 10745 CubitBoolean sheet ) const 10746 { 10747 //First check to make sure the data is all here. 10748 for ( int ii = ref_face_list.size(); ii > 0; ii-- ) 10749 { 10750 RefFace *ref_face = ref_face_list.get_and_step(); 10751 DLIList<Body*> bodies; 10752 ref_face->bodies(bodies); 10753 if ( bodies.size() > 1 ) 10754 { 10755 PRINT_ERROR("Can't create a volume with %s (surface %d) is attached to more\n" 10756 "than one volume, or if the attached body is not a sheet body.\n", 10757 ref_face->entity_name().c_str(), 10758 ref_face->id()); 10759 return CUBIT_FAILURE; 10760 } 10761 else if ( bodies.size() == 1 ) 10762 { 10763 if (!bodies.get()->is_sheet_body()) 10764 { 10765 PRINT_ERROR("Can't create a volume with %s (surface %d), it is\n" 10766 "attached to a body that is not a sheet body.\n", 10767 ref_face->entity_name().c_str(), 10768 ref_face->id()); 10769 return CUBIT_FAILURE; 10770 } 10771 } 10772 } 10773 10774 DLIList<TopologyEntity*> entity_list(ref_face_list.size()); 10775 DLIList<TopologyBridge*> bridge_list(ref_face_list.size()); 10776 DLIList<Surface*> surface_list(ref_face_list.size()); 10777 GeometryModifyEngine* gme; 10778 10779 CAST_LIST_TO_PARENT(ref_face_list, entity_list); 10780 gme = common_modify_engine(entity_list, bridge_list); 10781 CAST_LIST(bridge_list, surface_list, Surface); 10782 10783 if (!gme) { 10784 PRINT_ERROR("Surfaces do not share a common modify engine.\n"); 10785 return CUBIT_FAILURE; 10786 } 10787 10788 DLIList<TopologyEntity*> query_output, query_input(ref_face_list.size()); 10789 DLIList<Body*> body_list; 10790 10791 CAST_LIST_TO_PARENT(ref_face_list, query_input); 10792 ModelQueryEngine::instance()-> 10793 query_model( query_input, DagType::body_type(), query_output ); 10794 CAST_LIST( query_output, body_list, Body ); 10795 10796 int i; 10797 DLIList<RefFace*> free_face_list; 10798 for ( i=ref_face_list.size(); i--; ) 10799 { 10800 RefFace* ref_face = ref_face_list.get_and_step(); 10801 query_output.clean_out(); 10802 ModelQueryEngine::instance()-> 10803 query_model( *ref_face, DagType::body_type(), query_output ); 10804 if (!query_output.size()) 10805 free_face_list.append(ref_face); 10806 } 10807 10808 if (CubitUndo::get_undo_enabled()) 10809 CubitUndo::save_state_with_cubit_file(ref_face_list); 10810 10811 //get all the bodysm's 10812 DLIList<BodySM*> old_body_sm_list; 10813 for( i=body_list.size(); i--; ) 10814 { 10815 Body *tmp_body = body_list.get_and_step(); 10816 TopologyBridge *tb = tmp_body->bridge_manager()->topology_bridge(); 10817 BodySM *tmp_body_sm = CAST_TO(tb, BodySM); 10818 if( tmp_body_sm ) 10819 old_body_sm_list.append( tmp_body_sm ); 10820 } 10821 10822 // TODO: do I need a clear and a flush here? --KGM 10823 GeometryModifyTool::instance()->do_attribute_setup(); 10824 GeometryModifyTool::instance()->push_attributes_before_modify(old_body_sm_list); 10825 10826 DLIList<BodySM*> new_bodies_sm; 10827 CubitStatus stat = gme->create_solid_bodies_from_surfs( surface_list, new_bodies_sm, keep_old, heal, sheet ); 10828 DLIList<BodySM*> body_sm_list; 10829 for ( i=new_bodies_sm.size(); i--; ) 10830 body_sm_list.append( new_bodies_sm.get_and_step() ); 10831 10832 GeometryModifyTool::instance()->restore_vg_after_modify(new_bodies_sm, body_list, gme); 10833 GeometryModifyTool::instance()->remove_pushed_attributes(new_bodies_sm, body_list); 10834 10835 if (!finish_sm_op( body_list, body_sm_list, new_bodies)) 10836 { 10837 stat = CUBIT_FAILURE; 10838 if (CubitUndo::get_undo_enabled()) 10839 CubitUndo::remove_last_undo(); 10840 } 10841 else 10842 { 10843 if (CubitUndo::get_undo_enabled()) 10844 CubitUndo::note_result_bodies(new_bodies); 10845 } 10846 10847 GeometryModifyTool::instance()->do_attribute_cleanup(); 10848 10849 DLIList<int> id_list (free_face_list.size()); 10850 while (free_face_list.size()) 10851 { 10852 RefFace* ref_face = free_face_list.pop(); 10853 if (!ref_face->get_surface_ptr()) 10854 { 10855 id_list.append(ref_face->id()); 10856 GeometryQueryTool::instance()-> 10857 destroy_dead_entity( ref_face ); 10858 } 10859 } 10860 10861 GeometryQueryTool::instance()->cleanout_deactivated_geometry(); 10862 if (id_list.size()) 10863 CubitUtil::list_entity_ids( "Destroyed surface(s) ", id_list ); 10864 10865 //new_body = new_body_list.size() ? new_body_list.get() : 0; 10866 return stat; 10867 } 10868 10869 //------------------------------------------------------------------------- 10870 // Purpose : Check for virtual geometry 10871 // 10872 // Special Notes : 10873 // 10874 // Creator : Jason Kraftcheck 10875 // 10876 // Creation Date : 10/10/03 10877 //------------------------------------------------------------------------- 10878 bool GeometryModifyTool::contains_intermediate_geom( DLIList<Body*>& list ) const 10879 { 10880 DLIList<TopologyBridge*> bridges; 10881 list.reset(); 10882 for (int i = list.size(); i--; ) 10883 bridges.append(list.get_and_step()->get_body_sm_ptr()); 10884 return contains_intermediate_geom(bridges); 10885 } 10886 10887 //------------------------------------------------------------------------- 10888 // Purpose : Check for virtual geometry 10889 // 10890 // Special Notes : 10891 // 10892 // Creator : Jason Kraftcheck 10893 // 10894 // Creation Date : 10/10/03 10895 //------------------------------------------------------------------------- 10896 bool GeometryModifyTool::contains_intermediate_geom( 10897 DLIList<TopologyBridge*>& bridge_list ) const 10898 { 10899 DLIList<TopologyBridge*> child_list; 10900 while (bridge_list.size()) 10901 { 10902 TopologyBridge* bridge = bridge_list.pop(); 10903 TBOwner* bridge_owner = bridge->owner(); 10904 if (bridge_owner && !dynamic_cast<BridgeManager*>(bridge_owner)) 10905 return true; 10906 10907 child_list.clean_out(); 10908 bridge->get_children_virt(child_list); 10909 bridge_list += child_list; 10910 } 10911 return false; 10912 } 10913 10914 bool GeometryModifyTool::contains_partitions( DLIList<Body*>& list ) const 10915 { 10916 DLIList<TopologyBridge*> bridges; 10917 list.reset(); 10918 for (int i = list.size(); i--; ) 10919 bridges.append(list.get_and_step()->get_body_sm_ptr()); 10920 return contains_partitions(bridges); 10921 } 10922 10923 bool GeometryModifyTool::contains_composites( DLIList<Body*>& list ) const 10924 { 10925 DLIList<TopologyBridge*> bridges; 10926 list.reset(); 10927 for (int i = list.size(); i--; ) 10928 bridges.append(list.get_and_step()->get_body_sm_ptr()); 10929 return contains_composites(bridges); 10930 } 10931 10932 bool GeometryModifyTool::contains_composites( 10933 DLIList<TopologyBridge*>& bridge_list ) const 10934 { 10935 DLIList<TopologyBridge*> child_list; 10936 while (bridge_list.size()) 10937 { 10938 TopologyBridge* bridge = bridge_list.pop(); 10939 TBOwner* bridge_owner = bridge->owner(); 10940 if (bridge_owner && !dynamic_cast<BridgeManager*>(bridge_owner) && 10941 GeometryQueryTool::instance()->ige_is_composite(bridge_owner)) 10942 return true; 10943 10944 child_list.clean_out(); 10945 bridge->get_children_virt(child_list); 10946 bridge_list += child_list; 10947 } 10948 return false; 10949 } 10950 10951 bool GeometryModifyTool::contains_partitions( 10952 DLIList<TopologyBridge*>& bridge_list ) const 10953 { 10954 DLIList<TopologyBridge*> child_list; 10955 while (bridge_list.size()) 10956 { 10957 TopologyBridge* bridge = bridge_list.pop(); 10958 TBOwner* bridge_owner = bridge->owner(); 10959 if (bridge_owner && !dynamic_cast<BridgeManager*>(bridge_owner) && 10960 GeometryQueryTool::instance()->ige_is_partition(bridge_owner)) 10961 return true; 10962 10963 child_list.clean_out(); 10964 bridge->get_children_virt(child_list); 10965 bridge_list += child_list; 10966 } 10967 return false; 10968 } 10969 10970 10971 CubitBoolean GeometryModifyTool::same_modify_engine(DLIList<TopologyEntity*> &topo_list) const 10972 { 10973 GeometryModifyEngine *gePtr1 = get_engine(topo_list.get_and_step()); 10974 GeometryModifyEngine *gePtr2; 10975 for( int i = 1; i < topo_list.size(); i++) 10976 { 10977 gePtr2 = get_engine(topo_list.get_and_step()); 10978 if(gePtr1 != gePtr2) 10979 { 10980 return CUBIT_FALSE; 10981 } 10982 } 10983 return CUBIT_TRUE; 10984 } 10985 10986 CubitBoolean GeometryModifyTool::same_modify_engine(DLIList<RefEntity*> &ref_entity_list, 10987 CubitBoolean check_children) const 10988 { 10989 10990 DLIList<RefEntity*> complete_entity_list; 10991 10992 //Check the check_children option and check all the children if necessary 10993 if (check_children) 10994 { 10995 //Make a complete list of all the RefEntitys and their children 10996 DLIList<RefEntity*> temp = ref_entity_list; 10997 RefEntity* ref_entity_ptr; 10998 int i; 10999 for (i = 0; i < ref_entity_list.size(); i++) 11000 { 11001 ref_entity_ptr = ref_entity_list.get_and_step(); 11002 complete_entity_list.clean_out(); 11003 ref_entity_ptr->get_all_child_ref_entities(complete_entity_list); 11004 temp += complete_entity_list; 11005 } 11006 complete_entity_list.clean_out(); 11007 complete_entity_list.merge_unique(temp); 11008 } 11009 else 11010 complete_entity_list = ref_entity_list; 11011 11012 //Now make sure all the RefEntitys are from the same geometry engine 11013 DLIList<TopologyEntity*> te_list; 11014 CAST_LIST(complete_entity_list, te_list, TopologyEntity); 11015 return same_modify_engine(te_list); 11016 11017 } 11018 11019 CubitStatus 11020 GeometryModifyTool::trim_curve( RefEdge* trim_curve, 11021 const CubitVector& trim_vector, 11022 const CubitVector& keep_vector ) 11023 { 11024 // Use geometry engine to find intersections 11025 TopologyBridge* bridge = 0; 11026 GeometryModifyEngine* gme_ptr = get_engine(trim_curve, &bridge); 11027 Curve *new_curve = 0, *curve = dynamic_cast<Curve*>(bridge); 11028 11029 if (!gme_ptr || !curve) 11030 return CUBIT_FAILURE; 11031 11032 if( CubitUndo::get_undo_enabled() ) 11033 { 11034 DLIList<RefEdge*> tmp_ents(1); 11035 tmp_ents.append( trim_curve ); 11036 CubitUndo::save_state_with_cubit_file( tmp_ents ); 11037 } 11038 11039 new_curve = gme_ptr->trim_curve( curve, trim_vector, keep_vector ); 11040 if (!new_curve) 11041 { 11042 if( CubitUndo::get_undo_enabled() ) 11043 CubitUndo::remove_last_undo(); 11044 return CUBIT_FAILURE; 11045 } 11046 11047 GeometryQueryTool::instance()->destroy_dead_entity( trim_curve ); 11048 11049 RefEdge* new_edge = GeometryQueryTool::instance()->make_free_RefEdge(new_curve); 11050 11051 if( CubitUndo::get_undo_enabled() ) 11052 CubitUndo::note_result_entity( new_edge ); 11053 11054 PRINT_INFO("Created curve %d\n", new_edge->id()); 11055 11056 return CUBIT_SUCCESS; 11057 } 11058 11059 CubitStatus 11060 GeometryModifyTool::surface_intersection( RefFace *ref_face1, 11061 RefFace *ref_face2, 11062 DLIList<RefEdge*> &ref_edge_list ) 11063 { 11064 DLIList<TopologyEntity*> entity_list(2); 11065 DLIList<TopologyBridge*> bridge_list(2); 11066 entity_list.append(ref_face1); 11067 entity_list.append(ref_face2); 11068 GeometryModifyEngine* gme = common_modify_engine(entity_list, bridge_list); 11069 if (!gme) 11070 { 11071 PRINT_ERROR("Surfaces %d and %d do not share a common solid modeller.\n", 11072 ref_face1->id(), ref_face2->id() ); 11073 return CUBIT_FAILURE; 11074 } 11075 11076 bridge_list.reset(); 11077 Surface* surf0 = dynamic_cast<Surface*>(bridge_list.get_and_step()); 11078 Surface* surf1 = dynamic_cast<Surface*>(bridge_list.get()); 11079 11080 GeometryQueryEngine* gqe = surf0->get_geometry_query_engine(); 11081 // Note the user can set the following value through 11082 // set geometry accuracy <val> 11083 double resabs = gqe->get_sme_resabs_tolerance(); 11084 11085 DLIList<Curve*> curve_list; 11086 CubitStatus status = gme->surface_intersection( surf0, surf1, curve_list, resabs ); 11087 11088 if( status == CUBIT_FAILURE ) 11089 return CUBIT_FAILURE; 11090 11091 if( CubitUndo::get_undo_enabled() && curve_list.size() ) 11092 CubitUndo::save_state(); 11093 11094 int i; 11095 Curve *curve_ptr; 11096 RefEdge *ref_edge_ptr; 11097 curve_list.reset(); 11098 for( i=curve_list.size(); i--; ) 11099 { 11100 curve_ptr = curve_list.get_and_step(); 11101 ref_edge_ptr = GeometryQueryTool::instance()-> 11102 make_free_RefEdge( curve_ptr ); 11103 if( ref_edge_ptr ) 11104 ref_edge_list.append( ref_edge_ptr ); 11105 else 11106 delete curve_ptr; 11107 } 11108 11109 if( CubitUndo::get_undo_enabled() ) 11110 { 11111 DLIList<RefEntity*> tmp_list; 11112 for( i=ref_edge_list.size(); i--; ) 11113 tmp_list.append( ref_edge_list.get_and_step() ); 11114 CubitUndo::note_result_entities( tmp_list ); 11115 } 11116 11117 return CUBIT_SUCCESS; 11118 } 11119 11120 11121 RefEdge* 11122 GeometryModifyTool::create_arc(const CubitVector& position, 11123 double radius, 11124 double start_angle, 11125 double end_angle, 11126 CubitVector plane, 11127 CubitBoolean preview) 11128 { 11129 if(0 == gmeList.size()) 11130 { 11131 PRINT_WARNING("No active geometry engine.\n"); 11132 return NULL; 11133 } 11134 11135 if( radius <= GEOMETRY_RESABS ) 11136 { 11137 PRINT_ERROR("Values must be positive\n"); 11138 return NULL; 11139 } 11140 11141 if(preview) 11142 { 11143 gmeList.get()->create_arc(position,radius,start_angle,end_angle, plane, preview); 11144 return NULL; 11145 } 11146 11147 if( CubitUndo::get_undo_enabled() ) 11148 CubitUndo::save_state(); 11149 11150 Curve* curve = gmeList.get()->create_arc(position,radius,start_angle,end_angle, plane,preview); 11151 if (!curve) 11152 { 11153 if( CubitUndo::get_undo_enabled() ) 11154 CubitUndo::remove_last_undo(); 11155 return 0; 11156 } 11157 11158 RefEdge* result = GeometryQueryTool::instance()->make_free_RefEdge(curve); 11159 PRINT_INFO("Created curve %d\n", result->id()); 11160 11161 if( CubitUndo::get_undo_enabled() ) 11162 CubitUndo::note_result_entity( result ); 11163 return result; 11164 } 11165 11166 11167 11168 11169 RefEdge* 11170 GeometryModifyTool::create_arc_three( RefVertex* ref_vertex1, 11171 RefVertex* ref_vertex2, 11172 RefVertex* ref_vertex3, 11173 CubitBoolean full, 11174 CubitBoolean preview ) 11175 { 11176 DLIList<TopologyEntity*> entity_list(3); 11177 DLIList<TopologyBridge*> bridge_list(3); 11178 entity_list.append(ref_vertex1); 11179 entity_list.append(ref_vertex2); 11180 entity_list.append(ref_vertex3); 11181 GeometryModifyEngine* gme = common_modify_engine(entity_list, bridge_list); 11182 if (!gme) 11183 { 11184 PRINT_ERROR("Vertices do not share a common solid modeller.\n"); 11185 return 0; 11186 } 11187 11188 if(preview) 11189 { 11190 bridge_list.reset(); 11191 TBPoint* point0 = dynamic_cast<TBPoint*>(bridge_list.next(0)); 11192 TBPoint* point1 = dynamic_cast<TBPoint*>(bridge_list.next(1)); 11193 TBPoint* point2 = dynamic_cast<TBPoint*>(bridge_list.next(2)); 11194 gme->create_arc_three( point0, point1, point2, full,preview ); 11195 return NULL; 11196 } 11197 11198 //if we can reuse vertices, we decide here 11199 bool need_new_start_point = false; 11200 bool need_new_end_point = false; 11201 if( full ) 11202 { 11203 need_new_start_point = ref_vertex1->get_parents() > 0; 11204 if (need_new_start_point) 11205 { 11206 bridge_list.reset(); 11207 TBPoint *start_point = gme->make_Point( ref_vertex1->coordinates() ); 11208 bridge_list.change_to( start_point ); 11209 } 11210 } 11211 else 11212 { 11213 need_new_start_point = ref_vertex1->get_parents() > 0; 11214 need_new_end_point = ref_vertex3->get_parents() > 0; 11215 11216 if (need_new_start_point) 11217 { 11218 bridge_list.reset(); 11219 TBPoint *start_point = gme->make_Point( ref_vertex1->coordinates() ); 11220 bridge_list.change_to( start_point ); 11221 } 11222 if (need_new_end_point) 11223 { 11224 bridge_list.reset(); 11225 bridge_list.last(); 11226 TBPoint *end_point = gme->make_Point( ref_vertex3->coordinates()); 11227 bridge_list.change_to( end_point ); 11228 } 11229 } 11230 11231 if( CubitUndo::get_undo_enabled() ) 11232 { 11233 DLIList<RefVertex*> vertices_to_save; 11234 if( !need_new_start_point ) 11235 vertices_to_save.append( ref_vertex1 ); 11236 if( !need_new_end_point ) 11237 vertices_to_save.append( ref_vertex3 ); 11238 11239 if( vertices_to_save.size() ) 11240 CubitUndo::save_state_with_cubit_file( vertices_to_save, true ); 11241 else 11242 CubitUndo::save_state(); 11243 } 11244 11245 bridge_list.reset(); 11246 TBPoint* point0 = dynamic_cast<TBPoint*>(bridge_list.next(0)); 11247 TBPoint* point1 = dynamic_cast<TBPoint*>(bridge_list.next(1)); 11248 TBPoint* point2 = dynamic_cast<TBPoint*>(bridge_list.next(2)); 11249 Curve* curve = gme->create_arc_three( point0, point1, point2, full,preview ); 11250 if (!curve) 11251 { 11252 if( CubitUndo::get_undo_enabled() ) 11253 CubitUndo::remove_last_undo(); 11254 return 0; 11255 } 11256 11257 RefEdge* result = GeometryQueryTool::instance()->make_free_RefEdge(curve); 11258 PRINT_INFO("Created curve %d\n", result->id()); 11259 11260 if( CubitUndo::get_undo_enabled() ) 11261 CubitUndo::note_result_entity( result ); 11262 return result; 11263 11264 } 11265 11266 RefEdge* 11267 GeometryModifyTool::create_arc_three( RefEdge* ref_edge1, 11268 RefEdge* ref_edge2, 11269 RefEdge* ref_edge3, 11270 CubitBoolean full, 11271 CubitBoolean preview ) 11272 { 11273 DLIList<TopologyEntity*> entity_list(3); 11274 DLIList<TopologyBridge*> bridge_list(3); 11275 entity_list.append(ref_edge1); 11276 entity_list.append(ref_edge2); 11277 entity_list.append(ref_edge3); 11278 GeometryModifyEngine* gme = common_modify_engine(entity_list, bridge_list); 11279 if (!gme) 11280 { 11281 PRINT_ERROR("The input curves must be associated with a common solid modeller.\n"); 11282 return NULL; 11283 } 11284 11285 bridge_list.reset(); 11286 Curve* curve0 = dynamic_cast<Curve*>(bridge_list.next(0)); 11287 Curve* curve1 = dynamic_cast<Curve*>(bridge_list.next(1)); 11288 Curve* curve2 = dynamic_cast<Curve*>(bridge_list.next(2)); 11289 Curve* curve = gme->create_arc_three( curve0, curve1, curve2, full,preview ); 11290 if (!curve) 11291 return 0; 11292 11293 if( CubitUndo::get_undo_enabled() ) 11294 CubitUndo::save_state(); 11295 11296 RefEdge* result = GeometryQueryTool::instance()->make_free_RefEdge(curve); 11297 11298 if( CubitUndo::get_undo_enabled() ) 11299 CubitUndo::note_result_entity( result ); 11300 11301 PRINT_INFO("Created curve %d\n", result->id()); 11302 return result; 11303 } 11304 RefEdge* 11305 GeometryModifyTool::create_arc_radius( RefVertex* ref_vertex1, 11306 RefVertex* ref_vertex2, 11307 const CubitVector &normal, 11308 double radius, 11309 CubitBoolean other_arc, 11310 CubitBoolean full, 11311 CubitBoolean preview) 11312 { 11313 DLIList<TopologyEntity*> entity_list(2); 11314 DLIList<TopologyBridge*> bridge_list(2); 11315 entity_list.append(ref_vertex1); 11316 entity_list.append(ref_vertex2); 11317 GeometryModifyEngine* gme = common_modify_engine(entity_list, bridge_list); 11318 if (!gme) 11319 { 11320 PRINT_ERROR("Vertices do not share a common modify engine.\n"); 11321 return 0; 11322 } 11323 11324 11325 11326 CubitVector start = ref_vertex1->coordinates(); // Position on arc 11327 CubitVector end = ref_vertex2->coordinates(); // Position on arc 11328 11329 CubitVector center_vec=end-start; 11330 11331 CubitVector perp_vec=normal*center_vec; 11332 center_vec*=0.5; 11333 double b=radius*radius-center_vec.length_squared(); 11334 if(b>=0) 11335 { 11336 b=sqrt(b); 11337 } 11338 else 11339 { 11340 PRINT_ERROR("Radius must be greater than half the distance between the end vertices.\n"); 11341 return 0; 11342 } 11343 if(other_arc) 11344 b*=-1; 11345 11346 11347 perp_vec.normalize(); 11348 perp_vec*=b; 11349 11350 11351 center_vec=center_vec+perp_vec; 11352 11353 CubitVector center=start+center_vec; 11354 11355 if(preview) 11356 { 11357 bridge_list.reset(); 11358 TBPoint* point1 = dynamic_cast<TBPoint*>(bridge_list.next(0)); 11359 TBPoint* point2 = dynamic_cast<TBPoint*>(bridge_list.next(1)); 11360 gme->create_arc_radius(center,point1, point2, 11361 normal, radius, full,preview ); 11362 return NULL; 11363 } 11364 else 11365 { 11366 11367 //if we can reuse vertices, we decide here 11368 bool need_new_start_point=false, need_new_end_point=false; 11369 if( full ) 11370 { 11371 need_new_start_point = ref_vertex1->get_parents() > 0; 11372 if (need_new_start_point) 11373 { 11374 bridge_list.reset(); 11375 TBPoint *start_point = gme->make_Point( ref_vertex1->coordinates() ); 11376 bridge_list.change_to( start_point ); 11377 } 11378 } 11379 else 11380 { 11381 need_new_start_point = ref_vertex1->get_parents() > 0; 11382 need_new_end_point = ref_vertex2->get_parents() > 0; 11383 11384 if (need_new_start_point) 11385 { 11386 bridge_list.reset(); 11387 TBPoint *start_point = gme->make_Point( ref_vertex1->coordinates() ); 11388 bridge_list.change_to( start_point ); 11389 } 11390 if (need_new_end_point) 11391 { 11392 bridge_list.last(); 11393 TBPoint *end_point = gme->make_Point( ref_vertex2->coordinates()); 11394 bridge_list.change_to( end_point ); 11395 } 11396 } 11397 11398 if( CubitUndo::get_undo_enabled() ) 11399 { 11400 DLIList<RefVertex*> vertices_to_save; 11401 if( !need_new_start_point ) 11402 vertices_to_save.append( ref_vertex1 ); 11403 if( !need_new_end_point ) 11404 vertices_to_save.append( ref_vertex2 ); 11405 11406 if( vertices_to_save.size() ) 11407 CubitUndo::save_state_with_cubit_file( vertices_to_save, true ); 11408 else 11409 CubitUndo::save_state(); 11410 } 11411 11412 bridge_list.reset(); 11413 TBPoint* point1 = dynamic_cast<TBPoint*>(bridge_list.next(0)); 11414 TBPoint* point2 = dynamic_cast<TBPoint*>(bridge_list.next(1)); 11415 Curve* curve = gme->create_arc_radius(center,point1, point2, 11416 normal, radius, full,preview ); 11417 if (!curve) 11418 { 11419 if( CubitUndo::get_undo_enabled() ) 11420 CubitUndo::remove_last_undo(); 11421 return 0; 11422 } 11423 11424 RefEdge* result = GeometryQueryTool::instance()->make_free_RefEdge(curve); 11425 PRINT_INFO("Created curve %d\n", result->id()); 11426 11427 if( CubitUndo::get_undo_enabled() ) 11428 CubitUndo::note_result_entity( result ); 11429 11430 return result; 11431 } 11432 return 0; 11433 } 11434 11435 RefEdge* 11436 GeometryModifyTool::create_arc_center_edge( RefVertex* ref_vertex1, 11437 RefVertex* ref_vertex2, 11438 RefVertex* ref_vertex3, 11439 const CubitVector &normal, 11440 double radius, 11441 CubitBoolean full, 11442 CubitBoolean preview ) 11443 { 11444 DLIList<TopologyEntity*> entity_list(3); 11445 DLIList<TopologyBridge*> bridge_list(3); 11446 entity_list.append(ref_vertex1); 11447 entity_list.append(ref_vertex2); 11448 entity_list.append(ref_vertex3); 11449 GeometryModifyEngine* gme = common_modify_engine(entity_list, bridge_list); 11450 if (!gme) 11451 { 11452 PRINT_ERROR("Vertices do not share a common modify engine.\n"); 11453 return 0; 11454 } 11455 11456 if(preview) 11457 { 11458 TBPoint* point0 = dynamic_cast<TBPoint*>(bridge_list.next(0)); 11459 TBPoint* point1 = dynamic_cast<TBPoint*>(bridge_list.next(1)); 11460 TBPoint* point2 = dynamic_cast<TBPoint*>(bridge_list.next(2)); 11461 gme->create_arc_center_edge( point0, point1, point2, 11462 normal, radius, full,preview ); 11463 return NULL; 11464 11465 } 11466 11467 //if we can reuse vertices, we decide here 11468 bool need_new_start_point=false, need_new_end_point=false; 11469 if( full ) 11470 { 11471 need_new_start_point = ref_vertex2->get_parents() > 0; 11472 if (need_new_start_point) 11473 { 11474 bridge_list.reset(); 11475 bridge_list.step(1); 11476 TBPoint *start_point = gme->make_Point( ref_vertex2->coordinates() ); 11477 bridge_list.change_to( start_point ); 11478 } 11479 } 11480 else 11481 { 11482 need_new_start_point = ref_vertex2->get_parents() > 0; 11483 need_new_end_point = ref_vertex3->get_parents() > 0; 11484 11485 if (need_new_start_point) 11486 { 11487 bridge_list.reset(); 11488 bridge_list.step(); 11489 TBPoint *start_point = gme->make_Point( ref_vertex2->coordinates() ); 11490 bridge_list.change_to( start_point ); 11491 } 11492 if (need_new_end_point) 11493 { 11494 bridge_list.last(); 11495 TBPoint *end_point = gme->make_Point( ref_vertex3->coordinates()); 11496 bridge_list.change_to( end_point ); 11497 } 11498 } 11499 11500 if( CubitUndo::get_undo_enabled() ) 11501 { 11502 DLIList<RefVertex*> vertices_to_save; 11503 if( !need_new_start_point ) 11504 vertices_to_save.append( ref_vertex2 ); 11505 if( !need_new_end_point ) 11506 vertices_to_save.append( ref_vertex3 ); 11507 11508 if( vertices_to_save.size() ) 11509 CubitUndo::save_state_with_cubit_file( vertices_to_save, true ); 11510 else 11511 CubitUndo::save_state(); 11512 } 11513 11514 bridge_list.reset(); 11515 TBPoint* point0 = dynamic_cast<TBPoint*>(bridge_list.next(0)); 11516 TBPoint* point1 = dynamic_cast<TBPoint*>(bridge_list.next(1)); 11517 TBPoint* point2 = dynamic_cast<TBPoint*>(bridge_list.next(2)); 11518 Curve* curve = gme->create_arc_center_edge( point0, point1, point2, 11519 normal, radius, full ); 11520 if (!curve) 11521 { 11522 if( CubitUndo::get_undo_enabled() ) 11523 CubitUndo::remove_last_undo(); 11524 return 0; 11525 } 11526 11527 RefEdge* result = GeometryQueryTool::instance()->make_free_RefEdge(curve); 11528 PRINT_INFO("Created curve %d\n", result->id()); 11529 11530 if( CubitUndo::get_undo_enabled() ) 11531 CubitUndo::note_result_entity( result ); 11532 11533 return result; 11534 11535 } 11536 11537 CubitStatus 11538 GeometryModifyTool::create_curve_combine( DLIList<RefEdge*>& ref_edge_list, 11539 RefEdge *&new_ref_edge_ptr ) 11540 { 11541 DLIList<TopologyBridge*> bridge_list(ref_edge_list.size()); 11542 CubitStatus result = CUBIT_FAILURE; 11543 11544 int count = ref_edge_list.size(); 11545 if (count == 0) 11546 { 11547 PRINT_ERROR("No edges to combine.\n"); 11548 return result; 11549 } 11550 11551 DLIList<TopologyEntity*> entity_list(count); 11552 CAST_LIST_TO_PARENT( ref_edge_list, entity_list ); 11553 GeometryModifyEngine* gme = common_modify_engine(entity_list, bridge_list); 11554 if (!gme) 11555 { 11556 PRINT_ERROR("Edges do not share a common modify engine.\n"); 11557 return result; 11558 } 11559 11560 Curve* new_curve_ptr; 11561 DLIList<Curve*> curve_list(count); 11562 CAST_LIST( bridge_list, curve_list, Curve ); 11563 result = gme->create_curve_combine(curve_list, new_curve_ptr); 11564 if (new_curve_ptr) 11565 new_ref_edge_ptr = CAST_TO(new_curve_ptr->topology_entity(), RefEdge); 11566 11567 11568 return result; 11569 } 11570 11571 //------------------------------------------------------------------------- 11572 // Purpose : Find a common geometry engine 11573 // 11574 // Special Notes : 11575 // 11576 // Creator : Jason Kraftcheck 11577 // 11578 // Creation Date : 02/28/00 11579 //------------------------------------------------------------------------- 11580 GeometryModifyEngine* 11581 GeometryModifyTool::common_modify_engine( DLIList<TopologyEntity*>& topology_list, 11582 DLIList<TopologyBridge*>& engine_bridges, 11583 CubitBoolean allow_composites ) const 11584 { 11585 GeometryModifyEngine* gme_ptr = 0; 11586 if(allow_composites) 11587 { 11588 int i; 11589 engine_bridges.clean_out(); 11590 for(i=topology_list.size(); i--;) 11591 { 11592 TopologyEntity* topo_ptr = topology_list.get_and_step(); 11593 if (!topo_ptr) 11594 return (GeometryModifyEngine*)NULL; 11595 TopologyBridge *first_bridge = topo_ptr->bridge_manager()->topology_bridge(); 11596 GeometryQueryEngine *gqe = first_bridge->get_geometry_query_engine(); 11597 DLIList<TopologyBridge*> underlying_bridge_list; 11598 gqe->get_underlying_bridges(first_bridge, underlying_bridge_list); 11599 if(underlying_bridge_list.size() == 0) 11600 underlying_bridge_list.append(first_bridge); 11601 int k; 11602 for(k=underlying_bridge_list.size(); k--;) 11603 { 11604 TopologyBridge *bridge_ptr = underlying_bridge_list.get_and_step(); 11605 engine_bridges.append( bridge_ptr ); 11606 GeometryModifyEngine *cur_gme = get_engine(bridge_ptr); 11607 if(!gme_ptr) 11608 gme_ptr = cur_gme; 11609 else 11610 { 11611 if(gme_ptr != cur_gme) 11612 { 11613 gme_ptr = NULL; 11614 k=0; 11615 i=0; 11616 } 11617 } 11618 } 11619 } 11620 } 11621 else 11622 { 11623 topology_list.reset(); 11624 11625 TopologyEntity* topo_ptr = topology_list.get_and_step(); 11626 if (!topo_ptr) 11627 return (GeometryModifyEngine*)NULL; 11628 DLIList<TopologyBridge*> first_bridge_list; 11629 topo_ptr->bridge_manager()->get_bridge_list( first_bridge_list ); 11630 11631 first_bridge_list.reset(); 11632 for( int i = first_bridge_list.size(); i > 0; i-- ) 11633 { 11634 TopologyBridge* bridge_ptr = first_bridge_list.get_and_step(); 11635 engine_bridges.clean_out(); 11636 engine_bridges.append( bridge_ptr ); 11637 gme_ptr = get_engine(bridge_ptr); 11638 11639 if( !gme_ptr ) 11640 return (GeometryModifyEngine*)NULL; 11641 11642 topology_list.reset(); 11643 topology_list.step(); //skip first entry 11644 for( int j = topology_list.size(); j > 1; j-- ) 11645 { 11646 topo_ptr = topology_list.get_and_step(); 11647 bridge_ptr = topo_ptr->bridge_manager()->topology_bridge(gme_ptr->get_gqe()); 11648 if( bridge_ptr ) engine_bridges.append( bridge_ptr ); 11649 else break; 11650 } 11651 11652 if( engine_bridges.size() == topology_list.size() ) 11653 break; 11654 11655 gme_ptr = 0; 11656 } 11657 } 11658 if( !gme_ptr ) 11659 { 11660 engine_bridges.clean_out(); 11661 PRINT_ERROR("Entities do not belong to the same geometry engine.\n"); 11662 } 11663 return gme_ptr; 11664 } 11665 11666 //------------------------------------------------------------------------- 11667 // Purpose : Find common modify engine for Bodies 11668 // 11669 // Special Notes : 11670 // 11671 // Creator : Jason Kraftcheck 11672 // 11673 // Creation Date : 09/26/03 11674 //------------------------------------------------------------------------- 11675 GeometryModifyEngine* 11676 GeometryModifyTool::common_modify_engine( DLIList<Body*>& input, 11677 DLIList<BodySM*>& output) const 11678 { 11679 input.reset(); 11680 Body* body_ptr = input.get(); 11681 BodySM* body_sm_ptr = body_ptr->get_body_sm_ptr(); 11682 GeometryModifyEngine* engine = get_engine(body_sm_ptr); 11683 11684 for (int i = input.size(); i--; ) 11685 { 11686 body_ptr = input.get_and_step(); 11687 body_sm_ptr = body_ptr->get_body_sm_ptr(); 11688 output.append(body_sm_ptr); 11689 11690 if (!body_sm_ptr) 11691 { 11692 PRINT_ERROR("Body %d is invalid -- no attached BodySM.\n", body_ptr->id()); 11693 output.clean_out(); 11694 return 0; 11695 } 11696 11697 if (get_engine(body_sm_ptr) != engine) 11698 { 11699 output.clean_out(); 11700 return 0; 11701 } 11702 } 11703 11704 return engine; 11705 } 11706 11707 //------------------------------------------------------------------------- 11708 // Purpose : Get modify engine common to input RefFaces and RefEdges. 11709 // 11710 // Special Notes : Wrapper around the TopologyEntity/TopologyBridge form. 11711 // 11712 // Creator : Jason Kraftcheck 11713 // 11714 // Creation Date : 09/26/03 11715 //------------------------------------------------------------------------- 11716 GeometryModifyEngine* 11717 GeometryModifyTool::common_modify_engine( DLIList<RefFace*>& face_list, 11718 DLIList<RefEdge*>& edge_list, 11719 DLIList<Surface*>& surf_list, 11720 DLIList<Curve*>& curv_list, 11721 CubitBoolean allow_composites) const 11722 { 11723 int i; 11724 const int count = face_list.size() + edge_list.size(); 11725 DLIList<TopologyEntity*> entity_list(count); 11726 DLIList<TopologyBridge*> bridge_list(count); 11727 11728 face_list.reset(); 11729 edge_list.reset(); 11730 for (i = face_list.size(); i--; ) 11731 entity_list.append(face_list.get_and_step()); 11732 for (i = edge_list.size(); i--; ) 11733 entity_list.append(edge_list.get_and_step()); 11734 11735 GeometryModifyEngine* engine = common_modify_engine(entity_list, bridge_list, allow_composites); 11736 if (!engine) 11737 return 0; 11738 11739 entity_list.reset(); 11740 CAST_LIST(bridge_list, surf_list, Surface); 11741 CAST_LIST(bridge_list, curv_list, Curve ); 11742 if(allow_composites) 11743 { 11744 if(surf_list.size() >= face_list.size() && curv_list.size() >= edge_list.size()) 11745 return engine; 11746 else 11747 return 0; 11748 } 11749 else 11750 { 11751 if (surf_list.size() != face_list.size() || curv_list.size() != edge_list.size()) 11752 return 0; 11753 else 11754 return engine; 11755 } 11756 } 11757 11758 //------------------------------------------------------------------------- 11759 // Purpose : Get modify engine common to input RefFaces. 11760 // 11761 // Special Notes : Wrapper around the TopologyEntity/TopologyBridge form. 11762 // 11763 // Creator : Jason Kraftcheck 11764 // 11765 // Creation Date : 11/05/03 11766 //------------------------------------------------------------------------- 11767 GeometryModifyEngine* 11768 GeometryModifyTool::common_modify_engine( DLIList<RefFace*>& face_list, 11769 DLIList<Surface*>& surf_list, 11770 CubitBoolean allow_composites) const 11771 { 11772 const int size = face_list.size(); 11773 DLIList<TopologyEntity*> topo_list(size); 11774 DLIList<TopologyBridge*> geom_list(size); 11775 GeometryModifyEngine* result; 11776 11777 CAST_LIST_TO_PARENT( face_list, topo_list ); 11778 result = common_modify_engine( topo_list, geom_list, allow_composites ); 11779 11780 CAST_LIST( geom_list, surf_list, Surface ); 11781 return result; 11782 } 11783 11784 //------------------------------------------------------------------------- 11785 // Purpose : Get modify engine common to input RefEdges. 11786 // 11787 // Special Notes : Wrapper around the TopologyEntity/TopologyBridge form. 11788 // 11789 // Creator : Steve Storm 11790 // 11791 // Creation Date : 03/09/05 11792 //------------------------------------------------------------------------- 11793 GeometryModifyEngine* GeometryModifyTool::common_modify_engine( 11794 DLIList<RefEdge*>& edge_list, 11795 DLIList<Curve*>& curve_list, 11796 CubitBoolean allow_composites) const 11797 { 11798 const int size = edge_list.size(); 11799 DLIList<TopologyEntity*> topo_list(size); 11800 DLIList<TopologyBridge*> geom_list(size); 11801 GeometryModifyEngine* result; 11802 11803 CAST_LIST_TO_PARENT( edge_list, topo_list ); 11804 result = common_modify_engine( topo_list, geom_list, allow_composites ); 11805 11806 CAST_LIST( geom_list, curve_list, Curve ); 11807 return result; 11808 } 11809 11810 //------------------------------------------------------------------------- 11811 // Purpose : Get modify engine common to input RefVertices. 11812 // 11813 // Special Notes : Wrapper around the TopologyEntity/TopologyBridge form. 11814 // 11815 // Creator : Steve Storm 11816 // 11817 // Creation Date : 03/25/05 11818 //------------------------------------------------------------------------- 11819 GeometryModifyEngine* 11820 GeometryModifyTool::common_modify_engine( DLIList<RefVertex*>& vertex_list, 11821 DLIList<TBPoint*>& point_list, 11822 CubitBoolean allow_composites) const 11823 { 11824 const int size = vertex_list.size(); 11825 DLIList<TopologyEntity*> topo_list(size); 11826 DLIList<TopologyBridge*> geom_list(size); 11827 GeometryModifyEngine* result; 11828 11829 CAST_LIST_TO_PARENT( vertex_list, topo_list ); 11830 result = common_modify_engine( topo_list, geom_list, allow_composites ); 11831 11832 CAST_LIST( geom_list, point_list, TBPoint ); 11833 return result; 11834 } 11835 11836 //------------------------------------------------------------------------- 11837 // Purpose : Pull RefFaces with a common GeometryModifyEngine out of 11838 // the input ref_face_list. Place their surfaces in the 11839 // output surf_list, and return the common modify engine. 11840 // 11841 // Special Notes : the function returns a NULL pointer if a RefFace without 11842 // a modify engine is found in the input list. 11843 // 11844 // Creator : Steve Storm 11845 // 11846 // Creation Date : 03/02/08 11847 //------------------------------------------------------------------------- 11848 GeometryModifyEngine* 11849 GeometryModifyTool::pull_common_surfs( DLIList<RefFace*> &ref_face_list, 11850 DLIList<RefFace*> &common_face_list, 11851 DLIList<Surface*> &common_surf_list ) 11852 { 11853 int i; 11854 RefFace *ref_face_ptr; 11855 Surface *surf_ptr; 11856 11857 GeometryModifyEngine *gme1 = 0, *gme2 = 0; 11858 11859 ref_face_list.reset(); 11860 for( i=0; i<ref_face_list.size(); i++ ) 11861 { 11862 ref_face_ptr = ref_face_list.get(); 11863 surf_ptr = ref_face_ptr->get_surface_ptr(); 11864 11865 if( i==0 ) 11866 { 11867 common_face_list.append( ref_face_ptr ); 11868 common_surf_list.append( surf_ptr ); 11869 gme1 = get_engine( surf_ptr ); 11870 if (!gme1) 11871 { 11872 PRINT_ERROR("Surface %d does not have a modify engine.\n", ref_face_ptr->id()); 11873 return 0; 11874 } 11875 ref_face_list.change_to( NULL ); 11876 ref_face_list.step(); 11877 continue; 11878 } 11879 11880 gme2 = get_engine( surf_ptr ); 11881 if (!gme2) 11882 { 11883 PRINT_ERROR("Surface %d does not have a modify engine.\n", ref_face_ptr->id()); 11884 return 0; 11885 } 11886 11887 if( gme2 == gme1 ) 11888 { 11889 common_face_list.append( ref_face_ptr ); 11890 common_surf_list.append( surf_ptr ); 11891 ref_face_list.change_to( NULL ); 11892 } 11893 11894 ref_face_list.step(); 11895 } 11896 11897 ref_face_list.remove_all_with_value( NULL ); 11898 11899 return gme1; 11900 } 11901 11902 // Separates the list of bodies so that there is one body per volume 11903 // after a webcut. Checks the sepAfterWebcut flag. 11904 CubitStatus GeometryModifyTool::separate_body_after_webcut( DLIList<Body*> &input_list, 11905 DLIList<Body*> &output_list) const 11906 { 11907 //First see if we should spearate. 11908 if ( !sepAfterWebcut ) 11909 { 11910 output_list = input_list; 11911 return CUBIT_SUCCESS; 11912 } 11913 DLIList<Body*> temp_body_list; 11914 for ( int ii = input_list.size(); ii > 0; ii-- ) 11915 { 11916 Body *body_ptr = input_list.get_and_step(); 11917 temp_body_list.clean_out(); 11918 11919 bool undo_setting = CubitUndo::get_undo_enabled(); 11920 if( undo_setting == true ) 11921 CubitUndo::set_undo_enabled( false ); 11922 11923 split_body(body_ptr, temp_body_list); 11924 11925 if( undo_setting == true ) 11926 CubitUndo::set_undo_enabled( true ); 11927 11928 output_list += temp_body_list; 11929 } 11930 return CUBIT_SUCCESS; 11931 } 11932 11933 GeometryModifyEngine *GeometryModifyTool::get_engine(TopologyBridge *tb_ptr) const 11934 { 11935 int i; 11936 GeometryModifyEngine *gme; 11937 for (i = 0; i < gmeList.size(); i++) { 11938 gme = gmeList.next(i); 11939 if (gme->is_modify_engine(tb_ptr)) return gme; 11940 } 11941 return NULL; 11942 } 11943 11944 GeometryModifyEngine *GeometryModifyTool::get_engine(TopologyEntity *te_ptr, 11945 TopologyBridge **bridge) const 11946 { 11947 int i; 11948 GeometryModifyEngine *gme = 0; 11949 TopologyBridge* tb_ptr = NULL; 11950 BridgeManager* bm = te_ptr->bridge_manager(); 11951 DLIList<TopologyBridge*> bridges(bm->number_of_bridges()); 11952 bm->get_bridge_list(bridges); 11953 bridges.reset(); 11954 for (i = bridges.size(); !gme && i--; ) 11955 { 11956 tb_ptr = bridges.get_and_step(); 11957 gme = get_engine(tb_ptr); 11958 } 11959 11960 if (bridge && gme) 11961 *bridge = tb_ptr; 11962 11963 return gme; 11964 } 11965 11966 CubitStatus GeometryModifyTool::get_offset_intersections( RefEdge* ref_edge1, RefEdge* ref_edge2, 11967 DLIList<CubitVector>& intersection_list, 11968 double offset, CubitBoolean ext_first ) 11969 { 11970 DLIList<TopologyEntity*> entity_list(2); 11971 DLIList<TopologyBridge*> bridge_list(2); 11972 entity_list.append(ref_edge1); 11973 entity_list.append(ref_edge2); 11974 GeometryModifyEngine* gme_ptr1 = common_modify_engine(entity_list,bridge_list); 11975 11976 if( gme_ptr1 == 0 ) 11977 { 11978 PRINT_ERROR( "Curves %d and %d do not have the same underlying geometry modeling engine\n" 11979 " For intersection calculations, they must be the same\n", 11980 ref_edge1->id(), ref_edge2->id() ); 11981 return CUBIT_FAILURE; 11982 } 11983 11984 bridge_list.reset(); 11985 Curve* curve0 = dynamic_cast<Curve*>(bridge_list.next(0)); 11986 Curve* curve1 = dynamic_cast<Curve*>(bridge_list.next(1)); 11987 11988 return gme_ptr1->get_offset_intersections( curve0, curve1, intersection_list, 11989 offset, ext_first ); 11990 } 11991 11992 CubitStatus GeometryModifyTool::get_offset_intersections(RefEdge* ref_edge_ptr, 11993 RefFace* ref_face_ptr, 11994 DLIList<CubitVector> &intersection_list, 11995 double offset, 11996 CubitBoolean ext_surf ) 11997 { 11998 // If curve is straight and surface is planar, compute their intersection; 11999 // otherwise use the geometry engine to do it. 12000 12001 Curve* curve_ptr = ref_edge_ptr->get_curve_ptr(); 12002 Surface* surface_ptr = ref_face_ptr->get_surface_ptr(); 12003 12004 if( curve_ptr == NULL ) 12005 { 12006 PRINT_ERROR("Unable to retrieve underlying geometric entity of Curve %d\n" 12007 " This is a bug - please report it\n", ref_edge_ptr->id() ); 12008 return CUBIT_FAILURE; 12009 } 12010 12011 if( surface_ptr == NULL ) 12012 { 12013 PRINT_ERROR("Unable to retrieve underlying geometric entity of Surface %d\n" 12014 " This is a bug - please report it\n", ref_face_ptr->id() ); 12015 return CUBIT_FAILURE; 12016 } 12017 12018 // If straight line and plane, find location right here analytically. 12019 CubitVector pln_origin, pln_normal; 12020 CubitVector crv_origin, crv_direction; 12021 if( ref_face_ptr->get_point_normal( pln_origin, pln_normal ) && 12022 ref_edge_ptr->get_point_direction( crv_origin, crv_direction ) ) 12023 { 12024 double pln_orig[3], pln_norm[3]; 12025 pln_orig[0]=pln_origin.x(); pln_orig[1]=pln_origin.y(); pln_orig[2]=pln_origin.z(); 12026 pln_norm[0]=pln_normal.x(); pln_norm[1]=pln_normal.y(); pln_norm[2]=pln_normal.z(); 12027 12028 double crv_orig[3], crv_dir[3]; 12029 crv_orig[0]=crv_origin.x(); crv_orig[1]=crv_origin.y(); crv_orig[2]=crv_origin.z(); 12030 crv_dir[0]=crv_direction.x(); crv_dir[1]=crv_direction.y(); crv_dir[2]=crv_direction.z(); 12031 12032 AnalyticGeometryTool *agt = AnalyticGeometryTool::instance(); 12033 12034 if( agt->is_vec_perp( pln_norm, crv_dir ) ) 12035 { 12036 PRINT_ERROR( "Line is parallel to the plane - intersection not possible\n" ); 12037 return CUBIT_FAILURE; 12038 } 12039 12040 double ang = agt->angle_vec_vec( pln_norm, crv_dir ); 12041 if( ang > AGT_PI_DIV_2 ) 12042 ang = AGT_PI - ang; 12043 12044 double int_pnt[3]; 12045 agt->int_ln_pln( crv_orig, crv_dir, pln_orig, pln_norm, int_pnt ); 12046 12047 // ang2 is angle between line and plane 12048 double ang2 = AGT_PI_DIV_2 - ang; 12049 12050 double hypotenuse = offset/sin(ang2); 12051 12052 double final_pnt[3]; 12053 12054 agt->next_pnt( int_pnt, crv_dir, hypotenuse, final_pnt ); 12055 12056 double end1[3], end2[3]; 12057 CubitVector start, end; 12058 start = ref_edge_ptr->start_coordinates(); 12059 end = ref_edge_ptr->end_coordinates(); 12060 end1[0]=start.x(); end1[1]=start.y(); end1[2]=start.z(); 12061 end2[0]=end.x(); end2[1]=end.y(); end2[2]=end.z(); 12062 12063 CubitVector curve_position; 12064 if( agt->is_pnt_on_ln_seg( final_pnt, end1, end2 ) ) 12065 { 12066 curve_position.x( final_pnt[0] ); 12067 curve_position.y( final_pnt[1] ); 12068 curve_position.z( final_pnt[2] ); 12069 } 12070 else 12071 { 12072 agt->reverse_vec( crv_dir, crv_dir ); 12073 12074 agt->next_pnt( int_pnt, crv_dir, hypotenuse, final_pnt ); 12075 12076 if( agt->is_pnt_on_ln_seg( final_pnt, end1, end2 ) ) 12077 { 12078 curve_position.x( final_pnt[0] ); 12079 curve_position.y( final_pnt[1] ); 12080 curve_position.z( final_pnt[2] ); 12081 } 12082 else 12083 { 12084 PRINT_ERROR( "Resultant point does not lie on bounded curve\n" ); 12085 return CUBIT_FAILURE; 12086 } 12087 } 12088 intersection_list.append( curve_position ); 12089 } 12090 else 12091 { 12092 DLIList<TopologyEntity*> entity_list(2); 12093 DLIList<TopologyBridge*> bridge_list(2); 12094 entity_list.append(ref_edge_ptr); 12095 entity_list.append(ref_face_ptr); 12096 GeometryModifyEngine* gme_ptr1 = common_modify_engine(entity_list,bridge_list); 12097 12098 if( gme_ptr1 == 0 ) 12099 { 12100 PRINT_ERROR( "Curve %d and Surface %d do not have the same underlying geometry modeling engine\n" 12101 " For intersection calculations, they must be the same\n", 12102 ref_edge_ptr->id(), ref_face_ptr->id() ); 12103 return CUBIT_FAILURE; 12104 } 12105 12106 bridge_list.reset(); 12107 curve_ptr = dynamic_cast<Curve*>(bridge_list.next(0)); 12108 surface_ptr = dynamic_cast<Surface*>(bridge_list.next(1)); 12109 12110 // Use geometry engine to find intersections 12111 return gme_ptr1->get_offset_intersections( curve_ptr, surface_ptr, 12112 intersection_list, offset, ext_surf ); 12113 12114 } 12115 12116 return CUBIT_FAILURE; 12117 } 12118 12119 CubitStatus GeometryModifyTool::get_mid_plane( RefFace *ref_face1, 12120 RefFace *ref_face2, 12121 Body *body_to_trim_to, 12122 DLIList<RefFace*> &mid_plane_surfs ) const 12123 { 12124 if( ref_face1 == ref_face2 ) 12125 { 12126 PRINT_ERROR("Cannot create midplane between the same surface.\n" 12127 " Surface %d was entered twice\n", ref_face1->id() ); 12128 return CUBIT_FAILURE; 12129 } 12130 12131 BodySM* body_sm_to_trim_to = body_to_trim_to->get_body_sm_ptr(); 12132 GeometryModifyEngine *gme1_ptr = get_engine(body_sm_to_trim_to); 12133 if ( !gme1_ptr ) 12134 { 12135 PRINT_ERROR("Geometry can't be modified, no associated modify engine.\n"); 12136 return CUBIT_FAILURE; 12137 } 12138 12139 CubitVector normal_1, normal_2, point_1, point_2, point_3; 12140 CubitPlane plane_1, plane_2; 12141 CubitVector p_mid, n_mid; 12142 12143 point_1 = ref_face1->center_point(); 12144 point_2 = ref_face2->center_point(); 12145 12146 normal_1 = ref_face1->normal_at(point_1); 12147 normal_2 = ref_face2->normal_at(point_2); 12148 12149 plane_1 = CubitPlane(normal_1,point_1); 12150 plane_2 = CubitPlane(normal_2,point_2); 12151 12152 if(point_1 == point_2) 12153 { 12154 PRINT_ERROR("Since both surfaces share the same point, the midplane is not well-defined\n"); 12155 return CUBIT_FAILURE; 12156 } 12157 else 12158 { 12159 CubitVector temp1 = point_2; 12160 temp1 = plane_1.project(temp1); 12161 temp1 -= point_2; 12162 if ( temp1.length_squared() < GEOMETRY_RESABS*GEOMETRY_RESABS ) 12163 { 12164 PRINT_ERROR("Since both planes are the same, the mid-plane is not well-defined.\n"); 12165 return CUBIT_FAILURE; 12166 } 12167 } 12168 12169 if(plane_1.normal()==plane_2.normal() || plane_1.normal()==-plane_2.normal()) 12170 { 12171 p_mid = (point_1+point_2)/2; 12172 n_mid = plane_1.normal(); 12173 } 12174 else 12175 { 12176 12177 CubitVector direction_of_line; 12178 plane_1.intersect(plane_2,p_mid,direction_of_line); 12179 direction_of_line.normalize(); 12180 12181 // Find if point_1 and point_2 are on the line of intersection 12182 // If they are, then the mid-plane is not well-defined 12183 CubitVector p1 = point_1-p_mid; 12184 CubitVector p2 = point_2-p_mid; 12185 p1.normalize(); 12186 p2.normalize(); 12187 12188 if(p1==direction_of_line || p1==-direction_of_line) 12189 { 12190 PRINT_ERROR("P1 is on the line of intersection.\n"); 12191 return CUBIT_FAILURE; 12192 } 12193 12194 if(p2==direction_of_line || p2==-direction_of_line) 12195 { 12196 PRINT_ERROR("P2 is on the line of intersection.\n"); 12197 return CUBIT_FAILURE; 12198 } 12199 12200 CubitVector v1 = p1 - (p1%direction_of_line)*direction_of_line; 12201 v1.normalize(); 12202 12203 CubitVector v2 = p2 - (p2%direction_of_line)*direction_of_line; 12204 v2.normalize(); 12205 12206 n_mid = v1 - v2; 12207 n_mid.normalize(); 12208 } 12209 12210 CubitPlane mid_plane(n_mid, p_mid); 12211 point_1 = p_mid; 12212 //find three points that will define the infinite plane from the 12213 //mid plane. 12214 CubitVector test1(1,0,0), test1n(-1,0,0),test2(0,1,0); 12215 CubitVector direction1; 12216 //through the point in any direction just not along the 12217 //normal direction. 12218 if(n_mid != test1 && n_mid != test1n ) 12219 direction1 = test1 + n_mid; 12220 else 12221 direction1 = test2 + n_mid; 12222 12223 point_2 = p_mid + direction1; 12224 point_2 = mid_plane.project(point_2); 12225 12226 direction1 = point_2-point_1; 12227 CubitVector direction2 = direction1*n_mid; 12228 point_3 = point_1 + direction2; 12229 12230 BodySM* midplane_body_sm = NULL; 12231 CubitStatus ret = gme1_ptr->get_mid_plane(point_1, point_2, point_3, 12232 body_sm_to_trim_to, midplane_body_sm ); 12233 12234 if (midplane_body_sm) 12235 { 12236 Body *midplane_body; 12237 12238 midplane_body = GeometryQueryTool::instance()->make_Body(midplane_body_sm); 12239 12240 DLIList<RefFace*> ref_faces; 12241 midplane_body->ref_faces( ref_faces ); 12242 12243 //make each surface of the body into its own body 12244 int i; 12245 for( i=0; i<ref_faces.size(); i++ ) 12246 { 12247 RefEntity *new_entity_ptr; 12248 new_entity_ptr = GeometryModifyTool::instance()->copy_refentity(ref_faces.get_and_step()); 12249 RefFace *ref_face_ptr = CAST_TO(new_entity_ptr, RefFace); 12250 mid_plane_surfs.append( ref_face_ptr ); 12251 } 12252 GeometryQueryTool::instance()->delete_Body( midplane_body ); 12253 } 12254 else 12255 return CUBIT_FAILURE; 12256 12257 return ret; 12258 } 12259 12260 //============================================================================= 12261 // Function : get_planar_mid_surface 12262 // Member Type: LOCAL 12263 // Description: Calculates a mid-surface between 2 planar surfaces. 12264 // Author : Philippe Pebay 12265 // Date : 05/15/06 12266 //============================================================================= 12267 CubitStatus get_planar_mid_surface( RefFace* ref_face1, 12268 RefFace* ref_face2, 12269 BodySM* body_sm_to_trim_to, 12270 BodySM*& midsurface_body_sm, 12271 GeometryModifyEngine *gme_ptr ) 12272 { 12273 CubitVector normal_1, normal_2, point_1, point_2, point_3; 12274 CubitPlane plane_1, plane_2; 12275 CubitVector p_mid, n_mid; 12276 12277 point_1 = ref_face1->center_point(); 12278 point_2 = ref_face2->center_point(); 12279 12280 normal_1 = ref_face1->normal_at(point_1); 12281 normal_2 = ref_face2->normal_at(point_2); 12282 12283 plane_1 = CubitPlane(normal_1,point_1); 12284 plane_2 = CubitPlane(normal_2,point_2); 12285 12286 if(point_1 == point_2) 12287 { 12288 PRINT_ERROR( "In GeometryModifyTool:: get_planar_mid_surface\n" 12289 " Since both surfaces share the same point, the midsurface is not well-defined\n"); 12290 return CUBIT_FAILURE; 12291 } 12292 else 12293 { 12294 CubitVector temp1 = point_2; 12295 temp1 = plane_1.project(temp1); 12296 temp1 -= point_2; 12297 if ( temp1.length_squared() < GEOMETRY_RESABS*GEOMETRY_RESABS ) 12298 { 12299 PRINT_ERROR("In GeometryModifyTool:: get_planar_mid_surface\n" 12300 " Since both planes are the same, the midsurface is not well-defined.\n"); 12301 return CUBIT_FAILURE; 12302 } 12303 } 12304 12305 if ( ( normal_1.about_equal( normal_2 ) ) || ( (-normal_1).about_equal( normal_2 ) ) ) 12306 { 12307 p_mid = (point_1+point_2)/2; 12308 n_mid = plane_1.normal(); 12309 } 12310 else 12311 { 12312 CubitVector direction_of_line; 12313 plane_1.intersect(plane_2,p_mid,direction_of_line); 12314 direction_of_line.normalize(); 12315 12316 // Find if point_1 and point_2 are on the line of intersection 12317 // If they are, then the mid-plane is not well-defined 12318 CubitVector p1 = point_1-p_mid; 12319 CubitVector p2 = point_2-p_mid; 12320 p1.normalize(); 12321 p2.normalize(); 12322 12323 if(p1==direction_of_line || p1==-direction_of_line) 12324 { 12325 PRINT_ERROR("In GeometryModifyTool:: get_planar_mid_surface\n" 12326 " P1 is on the line of intersection.\n"); 12327 return CUBIT_FAILURE; 12328 } 12329 12330 if(p2==direction_of_line || p2==-direction_of_line) 12331 { 12332 PRINT_ERROR("In GeometryModifyTool:: get_planar_mid_surface\n" 12333 " P2 is on the line of intersection.\n"); 12334 return CUBIT_FAILURE; 12335 } 12336 12337 CubitVector v1 = p1 - (p1%direction_of_line)*direction_of_line; 12338 v1.normalize(); 12339 12340 CubitVector v2 = p2 - (p2%direction_of_line)*direction_of_line; 12341 v2.normalize(); 12342 12343 n_mid = v1 - v2; 12344 n_mid.normalize(); 12345 } 12346 12347 CubitPlane mid_plane(n_mid, p_mid); 12348 point_1 = p_mid; 12349 12350 //find three points that will define the infinite plane from the 12351 //mid plane.through the point in any direction just not along the 12352 //normal direction 12353 CubitVector Xdir(1,0,0), Ydir(0,1,0); 12354 CubitVector direction1; 12355 12356 if ( ( ! n_mid.about_equal( Xdir ) ) && ( ! (-n_mid).about_equal( Xdir ) ) ) 12357 direction1 = Xdir + n_mid; 12358 else 12359 direction1 = Ydir + n_mid; 12360 12361 point_2 = p_mid + direction1; 12362 point_2 = mid_plane.project(point_2); 12363 12364 direction1 = point_2-point_1; 12365 CubitVector direction2 = direction1*n_mid; 12366 point_3 = point_1 + direction2; 12367 12368 CubitStatus ret = gme_ptr->get_mid_plane(point_1, point_2, point_3, 12369 body_sm_to_trim_to, midsurface_body_sm ); 12370 return ret; 12371 } 12372 12373 //============================================================================= 12374 // Function : get_mid_surface 12375 // Member Type: PUBLIC 12376 // Description: Calculates a mid-surface between 2 surfaces (calls appropriate 12377 // specialized methods if needed). 12378 // Author : Philippe Pebay 12379 // Date : 03/07/06 12380 //============================================================================= 12381 CubitStatus GeometryModifyTool::get_mid_surface( RefFace *ref_face1, 12382 RefFace *ref_face2, 12383 Body *body_to_trim_to, 12384 DLIList<RefFace*> &mid_surface_surfs ) const 12385 { 12386 if( ref_face1 == ref_face2 ) 12387 { 12388 PRINT_ERROR("Cannot create midplane between the same surface.\n" 12389 " Surface %d was entered twice\n", ref_face1->id() ); 12390 return CUBIT_FAILURE; 12391 } 12392 12393 BodySM *body_sm_to_trim_to = body_to_trim_to->get_body_sm_ptr(); 12394 GeometryModifyEngine *gme1_ptr = get_engine(body_sm_to_trim_to); 12395 if ( !gme1_ptr ) 12396 { 12397 PRINT_ERROR("In GeometryModifyTool::get_mid_surface\n" 12398 " Geometry can't be modified, no associated modify engine.\n"); 12399 return CUBIT_FAILURE; 12400 } 12401 12402 bool found_case = false; 12403 CubitStatus ret = CUBIT_SUCCESS; 12404 BodySM* midsurface_body_sm = NULL; 12405 12406 // Plane to plane case 12407 if ( ( ref_face1->geometry_type() == PLANE_SURFACE_TYPE ) && ( ref_face2->geometry_type() == PLANE_SURFACE_TYPE ) ) 12408 { 12409 found_case = true; 12410 ret = get_planar_mid_surface( ref_face1, ref_face2, body_sm_to_trim_to, midsurface_body_sm, gme1_ptr ); 12411 } 12412 12413 // Quadric to quadric cases 12414 if ( ( ( ref_face1->geometry_type() == SPHERE_SURFACE_TYPE ) && ( ref_face2->geometry_type() == SPHERE_SURFACE_TYPE ) ) 12415 || 12416 ( ( ref_face1->geometry_type() == CONE_SURFACE_TYPE ) && ( ref_face2->geometry_type() == CONE_SURFACE_TYPE ) ) 12417 || 12418 ( ( ref_face1->geometry_type() == TORUS_SURFACE_TYPE ) && ( ref_face2->geometry_type() == TORUS_SURFACE_TYPE ) ) ) 12419 { 12420 found_case = true; 12421 DLIList<TopologyEntity*> entity_list(2); 12422 DLIList<TopologyBridge*> bridge_list(2); 12423 12424 entity_list.append(ref_face1); 12425 entity_list.append(ref_face2); 12426 GeometryModifyEngine* gme2_ptr = common_modify_engine(entity_list,bridge_list); 12427 12428 if( gme2_ptr == 0 ) 12429 { 12430 PRINT_ERROR( "In GeometryModifyTool::get_mid_surface\n" 12431 " Surfaces %d and %d do not have the same underlying geometry modeling engine.\n" 12432 " For midsurface calculations, they must be the same\n", 12433 ref_face1->id(), ref_face2->id() ); 12434 return CUBIT_FAILURE; 12435 } 12436 12437 if( gme1_ptr != gme2_ptr ) 12438 { 12439 PRINT_ERROR( "In GeometryModifyTool::get_mid_surface\n" 12440 " Body and surfaces do not have the same underlying geometry modeling engine.\n" 12441 " For midsurface calculations, they must be the same\n"); 12442 return CUBIT_FAILURE; 12443 } 12444 12445 bridge_list.reset(); 12446 Surface* surface1_ptr = dynamic_cast<Surface*>(bridge_list.next(0)); 12447 Surface* surface2_ptr = dynamic_cast<Surface*>(bridge_list.next(1)); 12448 12449 // Sphere to sphere case 12450 if ( ( ref_face1->geometry_type() == SPHERE_SURFACE_TYPE ) && ( ref_face2->geometry_type() == SPHERE_SURFACE_TYPE ) ) 12451 { 12452 ret = gme2_ptr->get_spheric_mid_surface( surface1_ptr, surface2_ptr, body_sm_to_trim_to, midsurface_body_sm ); 12453 } 12454 12455 // Cone to cone case 12456 if ( ( ref_face1->geometry_type() == CONE_SURFACE_TYPE ) && ( ref_face2->geometry_type() == CONE_SURFACE_TYPE ) ) 12457 { 12458 ret = gme2_ptr->get_conic_mid_surface( surface1_ptr, surface2_ptr, body_sm_to_trim_to, midsurface_body_sm ); 12459 } 12460 12461 // Torus to torus case 12462 if ( ( ref_face1->geometry_type() == TORUS_SURFACE_TYPE ) && ( ref_face2->geometry_type() == TORUS_SURFACE_TYPE ) ) 12463 { 12464 ret = gme2_ptr->get_toric_mid_surface( surface1_ptr, surface2_ptr, body_sm_to_trim_to, midsurface_body_sm ); 12465 } 12466 } 12467 12468 // Unsupported pair of surfaces 12469 if ( ! found_case ) 12470 { 12471 PRINT_ERROR("In GeometryModifyTool::get_mid_surface\n" 12472 " Midsurface calculation not yet supported for such a pair of surfaces.\n"); 12473 return CUBIT_FAILURE; 12474 } 12475 12476 if ( midsurface_body_sm ) 12477 { 12478 if(CubitUndo::get_undo_enabled()) 12479 CubitUndo::save_state(); 12480 12481 DLIList<Surface*> mid_surfaces; 12482 DLIList<Body*> new_bodies; 12483 midsurface_body_sm->surfaces( mid_surfaces); 12484 //make each surface of the body into its own body 12485 int i; 12486 for( i=0; i<mid_surfaces.size(); i++ ) 12487 { 12488 Surface *tmp_surface = mid_surfaces.get_and_step(); 12489 Surface* new_surface_ptr = gme1_ptr->make_Surface( tmp_surface ); 12490 12491 Body *new_Body = make_Body(new_surface_ptr); 12492 new_bodies.append( new_Body ); 12493 DLIList<RefFace*> ref_faces; 12494 new_Body->ref_faces(ref_faces); 12495 RefFace *ref_face_ptr = ref_faces.get(); 12496 mid_surface_surfs.append( ref_face_ptr ); 12497 } 12498 gme1_ptr->get_gqe()->delete_solid_model_entities( midsurface_body_sm ); 12499 12500 if( CubitUndo::get_undo_enabled() ) 12501 { 12502 if( new_bodies.size() ) 12503 CubitUndo::note_result_bodies( new_bodies ); 12504 else 12505 CubitUndo::remove_last_undo(); 12506 } 12507 12508 return ret; 12509 } 12510 else 12511 return CUBIT_FAILURE; 12512 } 12513 12514 CubitStatus GeometryModifyTool::set_default_gme(GeometryModifyEngine* GMEPtr) 12515 { 12516 if(!GMEPtr) 12517 return CUBIT_FAILURE; 12518 12519 int i; 12520 for (i = 0; i < gmeList.size(); i++) 12521 { 12522 if(GMEPtr == gmeList.get()) 12523 break; 12524 12525 gmeList.step(); 12526 } 12527 12528 if(i == gmeList.size()) 12529 return CUBIT_FAILURE; 12530 12531 GeometryModifyEngine* temp_ptr = gmeList.get(); 12532 gmeList.remove(); 12533 gmeList.insert_first(temp_ptr); 12534 return CUBIT_SUCCESS; 12535 } 12536 12537 //============================================================================= 12538 // Description: Consolidate common setup code for tweak surface operations 12539 // Author : Jason Kraftcheck 12540 // Date : 11/05/03 12541 //============================================================================= 12542 GeometryModifyEngine* 12543 GeometryModifyTool::tweak_setup( DLIList<RefFace*> &input_faces, 12544 const char* name, 12545 DLIList<Body*> &output_bodies, 12546 DLIList<Surface*> &output_surfaces, 12547 CubitBoolean allow_composites) 12548 { 12549 if( input_faces.size() == 0 ) 12550 { 12551 PRINT_ERROR( "No surfaces specified\n" ); 12552 return 0; 12553 } 12554 12555 //are any of the input faces merged? ...disallow that 12556 int i; 12557 for( i=input_faces.size(); i--; ) 12558 { 12559 RefFace *tmp_face = input_faces.get(); 12560 if( tmp_face->is_merged() ) 12561 { 12562 input_faces.change_to( NULL ); 12563 PRINT_ERROR("Surface %d is a merged surface. Cannot perform %s operation on it.\n" 12564 " Unmerge it first\n", tmp_face->id(), name ); 12565 } 12566 input_faces.step(); 12567 } 12568 input_faces.remove_all_with_value( NULL ); 12569 if( input_faces.size() == 0 ) 12570 return 0; 12571 12572 // Get parent bodies 12573 DLIList<TopologyEntity*> query_input(input_faces.size()), query_output; 12574 CAST_LIST_TO_PARENT(input_faces, query_input); 12575 ModelQueryEngine::instance() 12576 ->query_model( query_input, DagType::body_type(), query_output ); 12577 CAST_LIST(query_output, output_bodies, Body); 12578 12579 if(allow_composites) 12580 { 12581 if (!okay_to_modify( output_bodies, "TWEAK" )) 12582 return 0; 12583 } 12584 else 12585 { 12586 if ( contains_intermediate_geom(output_bodies)) 12587 { 12588 PRINT_ERROR("%s surfaces on volumes containing virtual geometry\n" 12589 " is not allowed.\n" 12590 " Delete virtual geometry on these volumes before operation.\n", 12591 name); 12592 return 0; 12593 } 12594 } 12595 12596 // Get engine and corresponding geom entities 12597 GeometryModifyEngine* gme_ptr; 12598 gme_ptr = common_modify_engine( input_faces, output_surfaces, allow_composites ); 12599 if (!gme_ptr) 12600 { 12601 PRINT_ERROR("%s surfaces on volumes containing surfaces from different\n" 12602 " geometry engines is not allowed.\n", name); 12603 } 12604 12605 return gme_ptr; 12606 } 12607 12608 //============================================================================= 12609 // Description: Consolidate common setup code for tweak curve operations 12610 // Author : Steve Storm 12611 // Date : 03/25/05 12612 //============================================================================= 12613 GeometryModifyEngine* 12614 GeometryModifyTool::tweak_setup( DLIList<RefEdge*> &input_curves, 12615 const char* name, 12616 DLIList<Body*> &output_bodies, 12617 DLIList<Curve*> &output_curves, 12618 CubitBoolean allow_composites ) 12619 { 12620 if( input_curves.size() == 0 ) 12621 { 12622 PRINT_ERROR( "No curves specified\n" ); 12623 return 0; 12624 } 12625 12626 //are any of the input curves merged? ...disallow that 12627 int i; 12628 for( i=input_curves.size(); i--; ) 12629 { 12630 RefEdge *tmp_edge = input_curves.get(); 12631 if( tmp_edge->is_merged() ) 12632 { 12633 input_curves.change_to( NULL ); 12634 PRINT_ERROR("Curve %d is a merged curve. Cannot perform %s operation on it.\n" 12635 " Unmerge it first\n", tmp_edge->id(), name ); 12636 } 12637 input_curves.step(); 12638 } 12639 input_curves.remove_all_with_value( NULL ); 12640 if( input_curves.size() == 0 ) 12641 return 0; 12642 12643 // Get parent bodies 12644 DLIList<TopologyEntity*> query_input(input_curves.size()), query_output; 12645 CAST_LIST_TO_PARENT(input_curves, query_input); 12646 ModelQueryEngine::instance() 12647 ->query_model( query_input, DagType::body_type(), query_output ); 12648 CAST_LIST(query_output, output_bodies, Body); 12649 12650 if(allow_composites) 12651 { 12652 if (!okay_to_modify( output_bodies, "TWEAK" )) 12653 return 0; 12654 } 12655 else 12656 { 12657 if ( contains_intermediate_geom(output_bodies)) 12658 { 12659 PRINT_ERROR("%s surfaces on volumes containing virtual geometry\n" 12660 " is not allowed.\n" 12661 " Delete virtual geometry on these volumes before operation.\n", 12662 name); 12663 return 0; 12664 } 12665 } 12666 12667 // Get engine and corresponding geom entities 12668 GeometryModifyEngine* gme_ptr; 12669 gme_ptr = common_modify_engine( input_curves, output_curves ); 12670 if (!gme_ptr) 12671 { 12672 PRINT_ERROR("%s curves on entities containing surfaces from different\n" 12673 " geometry engines is not allowed.\n", name); 12674 } 12675 12676 return gme_ptr; 12677 } 12678 12679 //============================================================================= 12680 // Description: Consolidate common setup code for tweak vertex operations 12681 // Author : Steve Storm 12682 // Date : 03/25/05 12683 //============================================================================= 12684 GeometryModifyEngine* 12685 GeometryModifyTool::tweak_setup( DLIList<RefVertex*> &input_vertices, 12686 const char* name, 12687 DLIList<Body*> &output_bodies, 12688 DLIList<TBPoint*> &output_points, 12689 CubitBoolean allow_composites ) 12690 { 12691 if( input_vertices.size() == 0 ) 12692 { 12693 PRINT_ERROR( "No vertices specified\n" ); 12694 return 0; 12695 } 12696 12697 //are any of the input vertices merged? ...disallow that 12698 int i; 12699 for( i=input_vertices.size(); i--; ) 12700 { 12701 RefVertex *tmp_vert = input_vertices.get(); 12702 if( tmp_vert->is_merged() ) 12703 { 12704 input_vertices.change_to( NULL ); 12705 PRINT_ERROR("Vertex %d is a merged vertex. Cannot perform %s operation on it.\n" 12706 " Unmerge it first\n", tmp_vert->id(), name ); 12707 } 12708 input_vertices.step(); 12709 } 12710 input_vertices.remove_all_with_value( NULL ); 12711 if( input_vertices.size() == 0 ) 12712 return 0; 12713 12714 // Get parent bodies 12715 DLIList<TopologyEntity*> query_input(input_vertices.size()), query_output; 12716 CAST_LIST_TO_PARENT(input_vertices, query_input); 12717 ModelQueryEngine::instance() 12718 ->query_model( query_input, DagType::body_type(), query_output ); 12719 CAST_LIST(query_output, output_bodies, Body); 12720 12721 if(allow_composites) 12722 { 12723 if (!okay_to_modify( output_bodies, "TWEAK" )) 12724 return 0; 12725 } 12726 else 12727 { 12728 if ( contains_intermediate_geom(output_bodies)) 12729 { 12730 PRINT_ERROR("%s surfaces on volumes containing virtual geometry\n" 12731 " is not allowed.\n" 12732 " Delete virtual geometry on these volumes before operation.\n", 12733 name); 12734 return 0; 12735 } 12736 } 12737 12738 // Get engine and corresponding geom entities 12739 GeometryModifyEngine* gme_ptr; 12740 gme_ptr = common_modify_engine( input_vertices, output_points, allow_composites ); 12741 if (!gme_ptr) 12742 { 12743 PRINT_ERROR("%s vertices on entities containing surfaces from different\n" 12744 " geometry engines is not allowed.\n", name); 12745 } 12746 12747 return gme_ptr; 12748 } 12749 12750 //============================================================================= 12751 // Description: The user selects a surface they would like to idealize and also selects a radius 12752 // size for fillets. The user also specifies whether to consider internal and/or external fillets. 12753 // The program will identify fillets which meet the users criteria and tweak remove them automatically. 12754 // There is also a preview and exclude curve capability. 12755 // Author : Jonathan Bugman 12756 // Date : 10/23/2008 12757 //============================================================================= 12758 CubitStatus GeometryModifyTool::idealize_fillet_geometry(DLIList<RefEntity*> idealize_entity, 12759 DLIList<RefEntity*> exclude_entity, 12760 double fillet_rad, 12761 CubitBoolean internal_flg, 12762 CubitBoolean external_flg, 12763 CubitBoolean preview) 12764 { 12765 //cast the DLIList<RefEntity> to a DLIList<RefFace> 12766 DLIList<RefFace*> face_to_idealize; 12767 CAST_LIST(idealize_entity, face_to_idealize, RefFace); 12768 12769 //grabbing geometry tolerance 12770 double geo_tol = GeometryQueryTool::instance()->get_sme_resabs_tolerance(),temp_fillet_radius; 12771 12772 //grabbing all the curve loops ONLY from surfaces which are a sheet body 12773 int y, i, j, z; 12774 DLIList<RefFace*> sheet_body_idealize_face; 12775 12776 for(i=0; i<face_to_idealize.size(); i++) 12777 { 12778 RefFace* target_face = face_to_idealize.get_and_step(); 12779 DLIList<Shell*> shell_list; 12780 target_face->shells(shell_list); 12781 for(j=0; j<shell_list.size(); j++) 12782 { 12783 Shell* target_shell = shell_list.get_and_step(); 12784 if(target_face->is_nonmanifold( (GroupingEntity*)target_shell ) ) 12785 { 12786 sheet_body_idealize_face.append(face_to_idealize[i]); 12787 } 12788 } 12789 } 12790 12791 face_to_idealize.clean_out(); 12792 12793 //this section is going to remove all excluded curves loopsm from the 'master' loopsm list 12794 DLIList<Curve*> exclude_cuves; 12795 DLIList <Body*> old_body_list; 12796 if(exclude_entity.size()>0) 12797 { 12798 //cast the exclude DLIList<RefEntity> to DLIList<RefEdge> 12799 DLIList<RefEdge*> exclude_edge; 12800 CAST_LIST(exclude_entity, exclude_edge, RefEdge); 12801 12802 //switching the DLIList<RefEdge> to DLIList<Curve> 12803 GeometryModifyEngine* gme_ptr1; 12804 gme_ptr1 = tweak_setup(exclude_edge,"idealize",old_body_list,exclude_cuves); 12805 if (NULL == gme_ptr1) { 12806 PRINT_ERROR("Unexpected NULL GeometryModifyEngine pointer.\n"); 12807 return CUBIT_FAILURE; 12808 } 12809 exclude_edge.clean_out(); 12810 } 12811 12812 //switching the DLIList<RefFace> to DLIList<Surface> 12813 GeometryModifyEngine* gme_ptr; 12814 DLIList<Surface*> sheet_body_idealize_surface; 12815 gme_ptr = tweak_setup(sheet_body_idealize_face,"idealize",old_body_list,sheet_body_idealize_surface); 12816 sheet_body_idealize_face.clean_out(); 12817 12818 //grab all the loops from each sheet body surface 12819 DLIList <LoopSM*> idealize_loopSM_list; 12820 for(y=0;y<sheet_body_idealize_surface.size();y++) 12821 { 12822 sheet_body_idealize_surface[y]->loopsms(idealize_loopSM_list); 12823 } 12824 sheet_body_idealize_surface.clean_out(); 12825 12826 //search through possible fillet curves filtering only for curves of type arc 12827 //if it is an arc, does it have a straight line on both sides of it, if so' 12828 //check the radius of the arc and if it passes test add it to the list of curves to be tweaked removed 12829 DLIList <Curve*> master_curve_remove_list,possible_fillet_arcs,potential_fillet,internal_fillet, external_fillet, attached_curves; 12830 CubitVector fillet_center_point, intersection_pt,arc_mid,test_point; 12831 DLIList <TBPoint*> arc_vertices; 12832 for(y=0;y<idealize_loopSM_list.size();y++) 12833 { 12834 idealize_loopSM_list[y]->curves(possible_fillet_arcs); 12835 //doing this as a performance boost, it'll keep the code out of the next couple of for loops for situations 12836 //where there is no fillet possible, for instance, a hole with 2 curves will never be a fillet 12837 if(possible_fillet_arcs.size()>3) 12838 { 12839 for(i=0;i<possible_fillet_arcs.size();i++) 12840 { 12841 if(possible_fillet_arcs[i]->geometry_type() == ARC_CURVE_TYPE && 12842 exclude_cuves.is_in_list(possible_fillet_arcs[i])==CUBIT_FALSE) 12843 { 12844 possible_fillet_arcs[i]->points(arc_vertices); 12845 //don't need to check for one point as in a hole because I have a check that there needs to be 12846 //at least 3 curves in the loop 12847 12848 //this is to check that there is only one curve attached to the arc 12849 for(z=0;z<arc_vertices.size();z++) 12850 { 12851 arc_vertices[z]->curves(attached_curves); 12852 if(attached_curves.size()!=2) 12853 { 12854 //I dont' think this break point is going to kick me far enough out of the for loop 12855 break; 12856 } 12857 } 12858 12859 possible_fillet_arcs[i]->mid_point(arc_mid); 12860 possible_fillet_arcs[i]->get_center_radius(fillet_center_point,temp_fillet_radius); 12861 test_point = arc_mid + geo_tol * (fillet_center_point-arc_mid); 12862 DLIList<Surface*> test_surf; 12863 idealize_loopSM_list[y]->surfaces(test_surf); 12864 12865 //this may be dangerous but I'm assuming that a loop is on only one surface 12866 CubitPointContainment cpc = test_surf[0]->point_containment(test_point); 12867 if(temp_fillet_radius <= fillet_rad && cpc==CUBIT_PNT_INSIDE) 12868 { 12869 external_fillet.append(possible_fillet_arcs[i]); 12870 } 12871 else if(temp_fillet_radius <= fillet_rad && cpc==CUBIT_PNT_OUTSIDE) 12872 { 12873 internal_fillet.append(possible_fillet_arcs[i]); 12874 } 12875 } 12876 } 12877 } 12878 possible_fillet_arcs.clean_out(); 12879 } 12880 12881 if(internal_flg==CUBIT_TRUE) 12882 { 12883 master_curve_remove_list+=internal_fillet; 12884 } 12885 if(external_flg==CUBIT_TRUE) 12886 { 12887 master_curve_remove_list+=external_fillet; 12888 } 12889 12890 //if no arcs are found to be removed, warn the user. 12891 if(master_curve_remove_list.size()==0) 12892 { 12893 PRINT_INFO( "Failed to find any fillets which met users requirements\n\n" ); 12894 //I'm returning success here even though no curves were found 12895 return CUBIT_SUCCESS; 12896 } 12897 else if(preview == CUBIT_TRUE) 12898 { 12899 DLIList<BodySM*> new_bodysm_list; 12900 bool old_error_flag = GET_ERROR_FLAG(); 12901 SET_ERROR_FLAG(false); // don't throw any tweak_remove errors 12902 12903 CubitStatus stat = gme_ptr->tweak_remove(master_curve_remove_list, new_bodysm_list,CUBIT_FALSE, CUBIT_TRUE ); 12904 12905 SET_ERROR_FLAG(old_error_flag); // turn errors back on 12906 if(stat==CUBIT_FAILURE) 12907 { 12908 PRINT_WARNING("At least one of the fillets which met your requirements \n" 12909 " can't be preview due to the curve's geometry\n"); 12910 } 12911 12912 //output the number of holes or slots which were found 12913 PRINT_INFO("Found %d fillets which met idealization parameters\n\n", master_curve_remove_list.size()); 12914 return CUBIT_SUCCESS; 12915 } 12916 else 12917 { 12918 DLIList<BodySM*> new_bodysm_list; 12919 bool old_error_flag = GET_ERROR_FLAG(); 12920 SET_ERROR_FLAG(false); // don't throw any tweak_remove errors 12921 12922 //pass master_curve_remove_list to the tweak_remove command 12923 CubitStatus stat = gme_ptr->tweak_remove(master_curve_remove_list, new_bodysm_list,CUBIT_FALSE, CUBIT_FALSE ); 12924 if(stat==CUBIT_FAILURE) 12925 { 12926 PRINT_WARNING("At least one of the fillets which met your requirements \n" 12927 " can't be tweaked due to the curve's geometry\n"); 12928 } 12929 SET_ERROR_FLAG(old_error_flag); // turn errors back on 12930 12931 //update DAG 12932 DLIList<Body*> new_body_list; 12933 stat = finish_sm_op( old_body_list, new_bodysm_list ,new_body_list ); 12934 //output the number of holes or slots which were found 12935 PRINT_INFO("Found %d fillets which met idealization parameters\n\n", master_curve_remove_list.size()); 12936 return CUBIT_SUCCESS; 12937 } 12938 } 12939 12940 //============================================================================= 12941 // Description: The user selects a surface they would like to idealize and also selects a radius 12942 // size for holes and or selects a radius and length for slots. The program will identify 12943 // 'holes' and 'slots' which meet the users criteria and tweak remove them automatically. 12944 // There is also a preview and exclude curve capability. 12945 // Author : Jonathan Bugman 12946 // Date : 10/23/2008 12947 //============================================================================= 12948 CubitStatus GeometryModifyTool::idealize_hole_slot_geometry(DLIList<RefEntity*> idealize_entity, 12949 DLIList<RefEntity*> exclude_entity, 12950 double arc_radius, 12951 double slot_arc_radius, 12952 double slot_length, 12953 CubitBoolean preview) 12954 { 12955 //cast the DLIList<RefEntity> to a DLIList<RefFace> 12956 DLIList<RefFace*> face_to_idealize; 12957 CAST_LIST(idealize_entity, face_to_idealize, RefFace); 12958 12959 //grabbing geometry tolerance 12960 double geo_tol = GeometryQueryTool::instance()->get_sme_resabs_tolerance(); 12961 12962 //grabbing all the curve loops ONLY from surfaces which are a sheet body 12963 int y=0, i=0, j=0; 12964 DLIList<RefFace*> sheet_body_idealize_face; 12965 12966 for(i=0; i<face_to_idealize.size(); i++) 12967 { 12968 RefFace* target_face = face_to_idealize.get_and_step(); 12969 DLIList<Shell*> shell_list; 12970 target_face->shells(shell_list); 12971 for(j=0; j<shell_list.size(); j++) 12972 { 12973 Shell* target_shell = shell_list.get_and_step(); 12974 if(target_face->is_nonmanifold( (GroupingEntity*)target_shell ) ) 12975 { 12976 sheet_body_idealize_face.append(face_to_idealize[i]); 12977 } 12978 } 12979 } 12980 12981 //if no faces to idealize that pass requirements, error out a warning message 12982 if(sheet_body_idealize_face.size()==0) 12983 { 12984 //I'm returning success here even though no surfaces found that meet shell requirements set above 12985 { 12986 PRINT_INFO( "Failed to find any feature(s) which met user requirements\n\n" ); 12987 } 12988 return CUBIT_SUCCESS; 12989 } 12990 12991 //temp_body_ptr = face_to_idealize[y]->body(); 12992 //if(temp_body_ptr->is_sheet_body()) 12993 //{ 12994 // sheet_body_idealize_face.append(face_to_idealize[y]); 12995 //} 12996 12997 face_to_idealize.clean_out(); 12998 12999 //switching the DLIList<RefFace> to DLIList<Surface> 13000 GeometryModifyEngine* gme_ptr; 13001 DLIList <Body*> old_body_list; 13002 DLIList<Surface*> sheet_body_idealize_surface; 13003 gme_ptr = tweak_setup(sheet_body_idealize_face,"idealize",old_body_list,sheet_body_idealize_surface); 13004 sheet_body_idealize_face.clean_out(); 13005 13006 //grab all the loops from each sheet body surface 13007 DLIList <LoopSM*> idealize_loopSM_list; 13008 for(y=0;y<sheet_body_idealize_surface.size();y++) 13009 { 13010 sheet_body_idealize_surface[y]->loopsms(idealize_loopSM_list); 13011 } 13012 sheet_body_idealize_surface.clean_out(); 13013 13014 //this section is going to remove all excluded curves loopsm from the 'master' loopsm list 13015 if(exclude_entity.size()>0) 13016 { 13017 //cast the exclude DLIList<RefEntity> to DLIList<RefEdge> 13018 DLIList<RefEdge*> exclude_edge; 13019 CAST_LIST(exclude_entity, exclude_edge, RefEdge); 13020 13021 //switching the DLIList<RefEdge> to DLIList<Curve> 13022 DLIList<Curve*> exclude_cuves; 13023 GeometryModifyEngine* gme_ptr1; 13024 gme_ptr1 = tweak_setup(exclude_edge,"idealize",old_body_list,exclude_cuves); 13025 if (NULL == gme_ptr1) { 13026 PRINT_ERROR("Unexpected NULL GeometryModifyEngine pointer.\n"); 13027 return CUBIT_FAILURE; 13028 } 13029 exclude_edge.clean_out(); 13030 13031 //grabbing all the curve loops from the given excluded curves 13032 DLIList <LoopSM*> exclude_loops; 13033 for(y=0;y<exclude_cuves.size();y++) 13034 { 13035 exclude_cuves[y]->loopsms(exclude_loops); 13036 } 13037 exclude_cuves.clean_out(); 13038 13039 //remove the excluded loops from the list of sheet body loopsms 13040 idealize_loopSM_list -= exclude_loops; 13041 } 13042 13043 //removing all the external loops from the list as they will not be tweak removed 13044 DLIList <LoopSM*> possible_internal_LoopSM_list; 13045 for(y=0;y<idealize_loopSM_list.size();y++) 13046 { 13047 if(idealize_loopSM_list[y]->loop_type() == LOOP_TYPE_HOLE) 13048 { 13049 possible_internal_LoopSM_list.append(idealize_loopSM_list[y]); 13050 } 13051 } 13052 idealize_loopSM_list.clean_out(); 13053 DLIList <Curve*> hole_curves_to_remove; //hole_curves_to_remove is the curves selected for removal out of the 'hole' search algorithm 13054 DLIList <Curve*> master_curve_remove_list; 13055 DLIList <LoopSM*> arc_LoopSM_list; 13056 DLIList <Surface*> temp_list; 13057 13059 //this begins the hole search algorithm 13060 //if no arc radius given, skip hole search algorithm 13061 if(arc_radius!=CUBIT_DBL_MAX) 13062 { 13063 DLIList <LoopSM*> not_hole_loop; //loops which don't meet the all curves are arc type filter 13064 DLIList <Curve*> possible_internal_arcs; 13065 13066 //search through possible internal curves filtering only for curves of type arc 13067 //if one of the curves in a loop is not an arc, add that loop to the not_hole_loop list 13068 for(y=0;y<possible_internal_LoopSM_list.size();y++) 13069 { 13070 possible_internal_arcs.clean_out(); 13071 possible_internal_LoopSM_list[y]->curves(possible_internal_arcs); 13072 for(i=0;i<possible_internal_arcs.size();i++) 13073 { 13074 temp_list.clean_out(); 13075 possible_internal_arcs[i]->surfaces(temp_list); 13076 //check whether or not curve is of arc type and whether it is attached to more than one surface 13077 if( possible_internal_arcs[i]->geometry_type() != ARC_CURVE_TYPE || temp_list.size() != 1) 13078 { 13079 not_hole_loop.append(possible_internal_LoopSM_list[y]); 13080 break; 13081 } 13082 } 13083 } 13084 13085 //change name of possible_internal_LoopSM_list to arc_LoopSM_list 13086 arc_LoopSM_list = possible_internal_LoopSM_list; 13087 //subtract from the possible loops the loops which don't have curves which are all arcs or are attached to more than two surfaces 13088 arc_LoopSM_list-=not_hole_loop; 13089 not_hole_loop.clean_out(); 13090 13091 //this next filter checks to make sure that all arcs of the same loop share the same 13092 //radius center within the geometry tolerance 13093 CubitVector arc_center_point, arc_center_point1; 13094 DLIList <LoopSM*> not_center_arc_loop; 13095 double rad_distance, temp_arc_radius , temp_arc_radius1; 13096 13097 //this for loop is going to check that each loops arc curves have the same center radius point 13098 //if not you can remove that loop as a possibility for being added to the tweak_remove command 13099 for(y=0;y<arc_LoopSM_list.size();y++) 13100 { 13101 //clean out curve list before grabbing a new loop 13102 hole_curves_to_remove.clean_out(); 13103 arc_LoopSM_list[y]->curves(hole_curves_to_remove); 13104 //iterate across the hole_curves_to_remove size 13105 for (i=0;i<hole_curves_to_remove.size();i++) 13106 { 13107 //if you are on the first index, we need to set a baseline radius point 13108 if(i==0) 13109 { 13110 hole_curves_to_remove[i]->get_center_radius(arc_center_point,temp_arc_radius); 13111 //if this is the only arc in the loop go ahead and check if it meets specified arc parameter 13112 //if it doesn't meet the users parameter add the loop to the not_center_arc_loop list 13113 if(temp_arc_radius >= arc_radius && hole_curves_to_remove.size()==1) 13114 { 13115 not_center_arc_loop.append(arc_LoopSM_list[y]); 13116 break; 13117 } 13118 } 13119 //now compare the other arc center points to the baseline, if it ever fails the users parameter 13120 //add the loop to the not_center_arc_loop list 13121 else 13122 { 13123 hole_curves_to_remove[i]->get_center_radius(arc_center_point1,temp_arc_radius1); 13124 rad_distance = arc_center_point.distance_between_squared(arc_center_point1); 13125 if(rad_distance > geo_tol || temp_arc_radius >= arc_radius) 13126 { 13127 not_center_arc_loop.append(arc_LoopSM_list[y]); 13128 break; 13129 } 13130 } 13131 } 13132 } 13133 13134 //remove loops which didn't have perfect circular holes from the arc_loopsm_list 13135 arc_LoopSM_list -= not_center_arc_loop; 13136 for(y=0;y<arc_LoopSM_list.size();y++) 13137 { 13138 arc_LoopSM_list[y]->curves(hole_curves_to_remove); 13139 } 13140 master_curve_remove_list+=hole_curves_to_remove; 13141 } 13142 13144 //this begins the slot search algorithm 13145 DLIList<LoopSM*> removable_slot_loop; 13146 if(slot_arc_radius!=CUBIT_DBL_MAX || slot_length!=CUBIT_DBL_MAX) 13147 { 13148 DLIList<LoopSM*> four_curve_possible_slot; 13149 DLIList<LoopSM*> possible_slot; 13150 DLIList<Curve*> internal_curves_in_loop; 13151 13152 //checks to make sure the loop has only four curves - may want to expand this in the future 13153 for(y=0;y<possible_internal_LoopSM_list.size();y++) 13154 { 13155 possible_internal_LoopSM_list[y]->curves(internal_curves_in_loop); 13156 if(internal_curves_in_loop.size()==4) 13157 { 13158 four_curve_possible_slot.append(possible_internal_LoopSM_list[y]); 13159 } 13160 internal_curves_in_loop.clean_out(); 13161 } 13162 13163 13164 //check to make sure it alternates straight line, arc, etc... 13165 for(y=0;y<four_curve_possible_slot.size();y++) 13166 { 13167 four_curve_possible_slot[y]->curves(internal_curves_in_loop); 13168 13169 if(internal_curves_in_loop[0]->geometry_type() == ARC_CURVE_TYPE && 13170 internal_curves_in_loop[1]->geometry_type() == STRAIGHT_CURVE_TYPE && 13171 internal_curves_in_loop[2]->geometry_type() == ARC_CURVE_TYPE && 13172 internal_curves_in_loop[3]->geometry_type() == STRAIGHT_CURVE_TYPE) 13173 { 13174 int num_of_surfs=0; 13175 for(i=0;i<internal_curves_in_loop.size();i++) 13176 { 13177 temp_list.clean_out(); 13178 internal_curves_in_loop[i]->surfaces(temp_list); 13179 num_of_surfs=num_of_surfs + temp_list.size(); 13180 } 13181 if(num_of_surfs==4) 13182 { 13183 possible_slot.append(four_curve_possible_slot[y]); 13184 } 13185 } 13186 else if(internal_curves_in_loop[0]->geometry_type() == STRAIGHT_CURVE_TYPE && 13187 internal_curves_in_loop[1]->geometry_type() == ARC_CURVE_TYPE && 13188 internal_curves_in_loop[2]->geometry_type() == STRAIGHT_CURVE_TYPE && 13189 internal_curves_in_loop[3]->geometry_type() == ARC_CURVE_TYPE) 13190 { 13191 int num_of_surfs=0; 13192 for(i=0;i<internal_curves_in_loop.size();i++) 13193 { 13194 temp_list.clean_out(); 13195 internal_curves_in_loop[i]->surfaces(temp_list); 13196 num_of_surfs=num_of_surfs + temp_list.size(); 13197 } 13198 if(num_of_surfs==4) 13199 { 13200 possible_slot.append(four_curve_possible_slot[y]); 13201 } 13202 } 13203 internal_curves_in_loop.clean_out(); 13204 } 13205 13206 CubitVector arc_center_point; 13207 double temp_arc_radius = CUBIT_DBL_MAX, curve_length = CUBIT_DBL_MAX; 13208 13209 //check to make sure that the rad and/or length meet users parameters 13210 for(y=0;y<possible_slot.size();y++) 13211 { 13212 possible_slot[y]->curves(internal_curves_in_loop); 13213 //if user specified rad, then passed rad_counter should = 2 after for loop completes 13214 //if length specified, length_counter should =2 after for loop completes 13215 int rad_counter = 0, length_counter = 0; 13216 for(i=0;i<internal_curves_in_loop.size();i++) 13217 { 13218 //if curve is an arc and user specified a radius enter if statement 13219 if( internal_curves_in_loop[i]->geometry_type() == ARC_CURVE_TYPE && slot_arc_radius!=CUBIT_DBL_MAX ) 13220 { 13221 //check the radius against the user inputed value 13222 internal_curves_in_loop[i]->get_center_radius(arc_center_point,temp_arc_radius); 13223 if(temp_arc_radius <= slot_arc_radius) 13224 { 13225 //if it passes rad test, add to rad_counter 13226 rad_counter++; 13227 } 13228 } 13229 else if(internal_curves_in_loop[i]->geometry_type() == STRAIGHT_CURVE_TYPE && slot_length!=CUBIT_DBL_MAX ) 13230 { 13231 //check the length against the user inputed value 13232 curve_length = internal_curves_in_loop[i]->get_arc_length(); 13233 if(curve_length <= slot_length) 13234 { 13235 //if it passes rad test, add to length_counter 13236 length_counter++; 13237 } 13238 } 13239 } 13240 13241 //checks that if user specified length and radius constraint that its parameter passes for all four curves 13242 if(slot_length!=CUBIT_DBL_MAX && slot_arc_radius!=CUBIT_DBL_MAX && rad_counter==2 && length_counter==2) 13243 { 13244 removable_slot_loop.append(possible_slot[y]); 13245 } 13246 13247 //if user only specified one length or arc parameter, it only needs to meet 2 criteria 13248 else if((slot_length!=CUBIT_DBL_MAX && length_counter==2) || (slot_arc_radius!=CUBIT_DBL_MAX && rad_counter==2)) 13249 { 13250 removable_slot_loop.append(possible_slot[y]); 13251 } 13252 internal_curves_in_loop.clean_out(); 13253 } 13254 //add removable loops curves to the master_curve_remove_list list 13255 for(y=0;y<removable_slot_loop.size();y++) 13256 { 13257 removable_slot_loop[y]->curves(master_curve_remove_list); 13258 } 13259 } 13260 13261 //if no arcs are found to be removed, warn the user. 13262 if(master_curve_remove_list.size()==0) 13263 { 13264 //I'm returning success here even though no curves were found 13265 { 13266 PRINT_INFO( "Failed to find any feature(s) which met user requirements\n\n" ); 13267 } 13268 return CUBIT_SUCCESS; 13269 } 13270 else if(preview == CUBIT_TRUE) 13271 { 13272 GfxPreview::clear(); 13273 13274 for(i=0; i<master_curve_remove_list.size();i++) 13275 { 13276 CubitStatus result; 13277 GMem g_mem; 13278 13279 // get the graphics 13280 result = master_curve_remove_list[i]->get_geometry_query_engine()-> 13281 get_graphics( master_curve_remove_list[i], &g_mem ); 13282 13283 if (result==CUBIT_FAILURE || g_mem.pointListCount == 0) 13284 { 13285 PRINT_WARNING("Unable to preview a curve\n" ); 13286 double len = master_curve_remove_list[i]-> 13287 length_from_u(master_curve_remove_list[i]->start_param(),master_curve_remove_list[i]->end_param()); 13288 13289 PRINT_WARNING("Curve len: %f\n",len); 13290 } 13291 13292 // Draw the polyline 13293 GfxPreview::draw_polyline( g_mem.point_list(), g_mem.pointListCount, CUBIT_BLUE_INDEX ); 13294 13295 } 13296 13297 //output the number of holes or slots which were found 13298 PRINT_INFO("Found %d holes and %d slots which met idealization parameters\n\n", arc_LoopSM_list.size(),removable_slot_loop.size()); 13299 GfxPreview::flush(); 13300 return CUBIT_SUCCESS; 13301 } 13302 else 13303 { 13304 DLIList<BodySM*> new_bodysm_list; 13305 //pass master_curve_remove_list to the tweak_remove command 13306 CubitStatus stat = gme_ptr->tweak_remove(master_curve_remove_list, new_bodysm_list,CUBIT_FALSE, CUBIT_FALSE ); 13307 if (CUBIT_SUCCESS != stat) { 13308 PRINT_ERROR("GeometryModifyEngine::tweak_remove failed.\n"); 13309 return stat; 13310 } 13311 13312 //update DAG 13313 DLIList<Body*> new_body_list; 13314 stat = finish_sm_op( old_body_list, new_bodysm_list ,new_body_list ); 13315 //output the number of holes or slots which were found 13316 PRINT_INFO("Found %d holes, and %d slots which met idealization parameters\n\n", arc_LoopSM_list.size(), removable_slot_loop.size()); 13317 return CUBIT_SUCCESS; 13318 } 13319 } 13320 13321 //============================================================================= 13322 // Description: Create drop down surfaces from the external edges of a surface to another surface with options 13323 // Use it primarially when you have a doubler plate situation and you need 13324 // to connect them together with surfaces to represent a weld 13325 // Author : Jonathan Bugman 13326 // Date : 02/07/2008 13327 //============================================================================= 13328 CubitStatus GeometryModifyTool::create_surface_doubler(DLIList<RefEntity*> doubler_entity, 13329 DLIList<RefEntity*> target_entity, 13330 DLIList<Body*> &body_list_out, 13331 CubitBoolean internal_flg, 13332 CubitBoolean extend_flg, 13333 CubitPlane *limit_plane, 13334 CubitVector sweep_direction, 13335 CubitBoolean preview) 13336 { 13337 //need to switch the DLIList<RefEntity> to a DLIList<RefFace> 13338 DLIList<RefFace*> doubler_face; 13339 DLIList<RefFace*> target_face; 13340 CAST_LIST( doubler_entity, doubler_face, RefFace); 13341 CAST_LIST( target_entity, target_face, RefFace); 13342 13343 bool enable_undo = CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE; 13344 if(enable_undo) 13345 { 13346 CubitUndo::save_state_with_cubit_file(doubler_face); 13347 } 13348 13349 DLIList <Surface*> doubler_surface; 13350 DLIList <Surface*> target_surface; 13351 DLIList <Body*> old_body_list; 13352 DLIList<RefFace*> tweak_face; 13353 DLIList<Surface*> tweak_surface; 13354 tweak_face+=doubler_face; 13355 tweak_face+=target_face; 13356 GeometryModifyEngine* gme_ptr; 13357 int ii=0, i=0; 13358 13359 gme_ptr = tweak_setup(tweak_face,"doubler",old_body_list,tweak_surface); 13360 int z; 13361 for(z=0;z<doubler_face.size();z++) 13362 { 13363 doubler_surface.append(tweak_surface[z]); 13364 } 13365 for(z=doubler_face.size();z<tweak_face.size();z++) 13366 { 13367 target_surface.append(tweak_surface[z]); 13368 } 13369 13370 DLIList<BodySM*> all_kept_bodies; 13371 DLIList<BodySM*> body_convert; 13372 DLIList<Surface*> copied_doubler_surface; 13373 DLIList <BodySM*> tweak_target_bodySM; 13374 13375 for(z=0;z<doubler_surface.size();z++) 13376 { 13377 copied_doubler_surface.append(gme_ptr->make_Surface(doubler_surface[z])); 13378 body_convert.append(copied_doubler_surface[z]->bodysm()); 13379 } 13380 13381 //each workflow is dependent on whether or not a sweep_direction is specified 13382 if(sweep_direction == CubitVector(0,0,0)) 13383 { 13384 DLIList<BodySM*> united_bodies; 13385 DLIList<BodySM*> separate_bodies; 13386 //this section takes all the doublers, unites them, and then splits them. If only one body 13387 //then skip the aforementioned two steps. 13388 if(doubler_surface.size()==1) 13389 { 13390 separate_bodies=body_convert; 13391 } 13392 else 13393 { 13394 if(gme_ptr->unite(body_convert,united_bodies) == CUBIT_FAILURE || united_bodies.size()==0 ) 13395 { 13396 PRINT_ERROR( "Command failed at unite command\n" ); 13397 13398 if(enable_undo) 13399 CubitUndo::remove_last_undo(); 13400 13401 return CUBIT_FAILURE; 13402 } 13403 13404 if(gme_ptr->split_body(united_bodies[0],separate_bodies) == CUBIT_FAILURE || separate_bodies.size()==0) 13405 { 13406 PRINT_ERROR( "Command failed at separate command\n" ); 13407 13408 if(enable_undo) 13409 CubitUndo::remove_last_undo(); 13410 13411 return CUBIT_FAILURE; 13412 } 13413 } 13414 for(z=0; z<separate_bodies.size();z++) 13415 { 13416 DLIList<Surface*> body_surface; 13417 separate_bodies[z]->surfaces(body_surface); 13418 13419 DLIList<CubitVector> doubler_surface_center_points; 13420 int d=0; 13421 for(d=0;d<body_surface.size();d++) 13422 { 13423 doubler_surface_center_points.append(body_surface[d]->bounding_box().center()); 13424 } 13425 CubitVector doubler_normal,doubler_center_pt,doubler_to_target_vector,target_center_pt; 13426 double extrude_distance = 0.0; 13427 13428 //make sure that the normal of the surface is pointing towards the target surface 13429 //the thicken command thickens in the direction of the surface normal, normals are checked using dot product check 13430 CubitVector center_pt = body_surface[0]->bounding_box().center(); 13431 body_surface[0]->closest_point(center_pt,&doubler_center_pt,&doubler_normal); 13432 //adding this for loop because of l bracket doublers may have the first target surface perpendicular to an opposite side doubler surface 13433 //resulting in the code erroneously failing 13434 double dot=0.0; 13435 int mm; 13436 for(mm=0; mm<target_surface.size();mm++) 13437 { 13438 target_surface[mm]->closest_point_trimmed(doubler_center_pt, target_center_pt); 13439 doubler_to_target_vector = target_center_pt - doubler_center_pt; 13440 dot = doubler_to_target_vector.x()*doubler_normal.x()+doubler_to_target_vector.y()*doubler_normal.y()+doubler_to_target_vector.z()*doubler_normal.z(); 13441 if(fabs(dot)>1E-6) 13442 { 13443 mm=target_surface.size(); 13444 } 13445 } 13446 if(fabs(dot)<1E-6) 13447 { 13448 PRINT_ERROR( "Doubler and target surface are touching or are perpendicular to each other\n" ); 13449 for(ii =0;ii<separate_bodies.size();ii++) 13450 { 13451 GeometryQueryEngine* gqe = separate_bodies[ii]->get_geometry_query_engine(); 13452 gqe->delete_solid_model_entities(separate_bodies[ii]); 13453 } 13454 13455 if(enable_undo) 13456 CubitUndo::remove_last_undo(); 13457 13458 return CUBIT_FAILURE; 13459 } 13460 else if(dot < 0) 13461 { 13462 if(gme_ptr->reverse_body(separate_bodies[z])==CUBIT_FAILURE) 13463 { 13464 PRINT_ERROR( "Command failed at reverse body command.\n" ); 13465 for(ii =0;ii<separate_bodies.size();ii++) 13466 { 13467 GeometryQueryEngine* gqe = separate_bodies[ii]->get_geometry_query_engine(); 13468 gqe->delete_solid_model_entities(separate_bodies[ii]); 13469 } 13470 13471 if(enable_undo) 13472 CubitUndo::remove_last_undo(); 13473 13474 return CUBIT_FAILURE; 13475 } 13476 extrude_distance = 0.0001; 13477 } 13478 else 13479 { 13480 extrude_distance = 0.0001; 13481 } 13482 13483 DLIList<BodySM*> thickened_doubler_bodySM; 13484 DLIList<BodySM*> current_body; 13485 current_body.append(separate_bodies[z]); 13486 13487 if(gme_ptr->thicken(current_body,thickened_doubler_bodySM,extrude_distance,CUBIT_FALSE) == CUBIT_FAILURE || thickened_doubler_bodySM.size()==0) 13488 { 13489 PRINT_ERROR( "Command failed at thicken command, this may be due to using a non-OCC geometry engine\n" ); 13490 for(ii =0;ii<separate_bodies.size();ii++) 13491 { 13492 GeometryQueryEngine* gqe = separate_bodies[ii]->get_geometry_query_engine(); 13493 gqe->delete_solid_model_entities(separate_bodies[ii]); 13494 } 13495 13496 if(enable_undo) 13497 CubitUndo::remove_last_undo(); 13498 13499 return CUBIT_FAILURE; 13500 } 13501 13502 //need to grab the newly created surface opposite the user selected one from the thicken function to carry it through for the tweak target 13503 DLIList<Surface*> thicken_surfaces; 13504 thickened_doubler_bodySM[0]->surfaces(thicken_surfaces); 13505 DLIList <Surface*> post_thicken_doublers; 13506 13507 int y=0; 13508 for(y=0;y<doubler_surface_center_points.size();y++) 13509 { 13510 doubler_center_pt = doubler_surface_center_points[y]; 13511 int r=0; 13512 for(r=0;r<thicken_surfaces.size();r++) 13513 { 13514 CubitVector test_center_pt = thicken_surfaces[r]->bounding_box().center(); 13515 if((test_center_pt-doubler_center_pt).length()<=.000001) 13516 { 13517 post_thicken_doublers.append(thicken_surfaces[r]); 13518 } 13519 } 13520 } 13521 13522 DLIList <LoopSM*> doubler_loopSM_list; 13523 DLIList <Curve*> doubler_external_curves; 13524 Curve* test_external_curves1 = NULL; 13525 Curve* test_external_curves2 = NULL; 13526 13527 //need to do this in order to grab all curves, not just external IMPORTANT:THIS HAS TO BE DONE BEFORE THE tweak? COMMAND! 13528 for(y=0;y<post_thicken_doublers.size();y++) 13529 { 13530 post_thicken_doublers[y]->loopsms(doubler_loopSM_list); 13531 } 13532 for(i=0;i<doubler_loopSM_list.size();i++) 13533 { 13534 doubler_loopSM_list[i]->curves(doubler_external_curves); 13535 } 13536 13537 doubler_loopSM_list.clean_out(); 13538 tweak_target_bodySM.clean_out(); 13539 DLIList <LoopSM*> test_loopSM_list; 13540 DLIList <Curve*> thicken_external_curves; 13541 DLIList <Surface*> tweak_target_surface = thicken_surfaces; 13542 13543 //stepping through the surfaces from the thicken body 13544 for(i=0; i < thicken_surfaces.size(); i++) 13545 { 13546 thicken_surfaces[i]->loopsms(test_loopSM_list); 13547 //grabbing the external curves from the current thicken_surface 13548 test_loopSM_list[0]->curves(thicken_external_curves); 13549 test_loopSM_list.clean_out(); 13550 int j=0; 13551 for(j=0;j<thicken_external_curves.size();j++) 13552 { 13553 //step through the first curve 13554 test_external_curves1 = thicken_external_curves[j]; 13555 int k=0; 13556 for(k=0; k<doubler_external_curves.size();k++) 13557 { 13558 //while stepping through the doubler plate curves, compare them to the test_test_surface curves 13559 test_external_curves2 = doubler_external_curves[k]; 13560 13561 //if the two are equal, they are touching the doulber and therefore are either the side surfaces or the doubler 13562 if(test_external_curves2 == test_external_curves1) 13563 { 13564 //remove the surface from the tweak_target_surface list 13565 tweak_target_surface.remove_all_with_value(thicken_surfaces[i]); 13566 break; 13567 } 13568 } 13569 if(test_external_curves2 == test_external_curves1) 13570 { 13571 break; 13572 } 13573 13574 } 13575 thicken_external_curves.clean_out(); 13576 } 13577 13578 //pass the found opposite surface into the tweak_target routine 13579 if(gme_ptr->tweak_target(tweak_target_surface,target_surface,tweak_target_bodySM,extend_flg,limit_plane) == CUBIT_FAILURE || tweak_target_bodySM.size()==0) 13580 { 13581 PRINT_ERROR( "Command failed at Tweak_Target routine\n" ); 13582 for(ii =0;ii<thickened_doubler_bodySM.size();ii++) 13583 { 13584 GeometryQueryEngine* gqe = thickened_doubler_bodySM[ii]->get_geometry_query_engine(); 13585 gqe->delete_solid_model_entities(thickened_doubler_bodySM[ii]); 13586 } 13587 13588 if(enable_undo) 13589 CubitUndo::remove_last_undo(); 13590 13591 return CUBIT_FAILURE; 13592 } 13593 13594 //fill out a tweak_body_surface list from tweak_target routine 13595 DLIList<Surface*> tweak_body_surfaces; 13596 tweak_target_bodySM[0]->surfaces(tweak_body_surfaces); 13597 DLIList <Curve*> tweak_external_curves; 13598 doubler_external_curves.clean_out(); 13599 13600 //refilling DLIList's as needed based on internal_flg 13601 //if we are not keeping internal surfaces we do not want it's curves in the doubler_external_curves list 13602 //otherwise if we are, we do want the curves in the list for the following sections for loop 13603 if(internal_flg==CUBIT_FALSE) 13604 { 13605 int j=0; 13606 for(i=0;i<post_thicken_doublers.size();i++) 13607 { 13608 post_thicken_doublers[i]->loopsms(doubler_loopSM_list); 13609 for(j=0;j<doubler_loopSM_list.size();j++) 13610 { 13611 LoopType loop_type = doubler_loopSM_list[j]->loop_type(); 13612 if(loop_type == LOOP_TYPE_EXTERNAL || 13613 loop_type == LOOP_TYPE_U_PERIODIC || 13614 loop_type == LOOP_TYPE_V_PERIODIC) 13615 { 13616 doubler_loopSM_list[j]->curves(doubler_external_curves); 13617 break; 13618 } 13619 } 13620 doubler_loopSM_list.clean_out(); 13621 } 13622 } 13623 else 13624 { 13625 for(i=0;i<post_thicken_doublers.size();i++) 13626 { 13627 post_thicken_doublers[i]->loopsms(doubler_loopSM_list); 13628 } 13629 for(i=0;i<doubler_loopSM_list.size();i++) 13630 { 13631 doubler_loopSM_list[i]->curves(doubler_external_curves); 13632 } 13633 13634 } 13635 13636 DLIList <Surface*> surfaces_to_keep; 13637 for(i=0;i<tweak_body_surfaces.size();i++) 13638 { 13639 tweak_body_surfaces[i]->loopsms(test_loopSM_list); 13640 13641 if(test_loopSM_list.size()==0) 13642 { 13643 PRINT_ERROR( "Command failed to find any doubler drop down curves\n" ); 13644 for(ii =0;ii<thickened_doubler_bodySM.size();ii++) 13645 { 13646 GeometryQueryEngine* gqe = thickened_doubler_bodySM[ii]->get_geometry_query_engine(); 13647 gqe->delete_solid_model_entities(thickened_doubler_bodySM[ii]); 13648 } 13649 13650 if(enable_undo) 13651 CubitUndo::remove_last_undo(); 13652 13653 return CUBIT_FAILURE; 13654 } 13655 13656 test_loopSM_list[0]->curves(tweak_external_curves); 13657 test_loopSM_list.clean_out(); 13658 13659 int j=0; 13660 for(j=0;j<tweak_external_curves.size();j++) 13661 { 13662 test_external_curves1 = tweak_external_curves[j]; 13663 13664 int k=0; 13665 for(k=0; k<doubler_external_curves.size();k++) 13666 { 13667 //while stepping through the doubler plate curves, compare them to the test_loop_list 13668 test_external_curves2 = doubler_external_curves[k]; 13669 13670 if(test_external_curves2 == test_external_curves1) 13671 { 13672 surfaces_to_keep.append(tweak_body_surfaces[i]); 13673 break; 13674 } 13675 } 13676 if(test_external_curves2 == test_external_curves1) 13677 { 13678 break; 13679 } 13680 } 13681 tweak_external_curves.clean_out(); 13682 } 13683 13684 if(surfaces_to_keep.size()==0) 13685 { 13686 PRINT_ERROR( "Failed to find and keep surfaces\n" ); 13687 for(ii =0;ii<tweak_target_bodySM.size();ii++) 13688 { 13689 GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine(); 13690 gqe->delete_solid_model_entities(tweak_target_bodySM[ii]); 13691 } 13692 13693 if(enable_undo) 13694 CubitUndo::remove_last_undo(); 13695 13696 return CUBIT_FAILURE; 13697 } 13698 13699 //do this to remove the copied_doubler_surface since we no longer need the surface anymore 13700 int c=0; 13701 for(c=0;c<post_thicken_doublers.size();c++) 13702 { 13703 surfaces_to_keep.remove_all_with_value(post_thicken_doublers[c]); 13704 } 13705 13706 DLIList <Surface*> surfaces_to_remove = tweak_body_surfaces; 13707 surfaces_to_remove -= surfaces_to_keep; 13708 DLIList<BodySM*> resulting_bodies; 13709 13710 //remove all surfaces in the surfaces_to_remove list 13711 if(gme_ptr->tweak_remove(surfaces_to_remove,resulting_bodies,CUBIT_FALSE) == CUBIT_FAILURE || resulting_bodies.size()==0) 13712 { 13713 PRINT_ERROR( "Command failed at Tweak_Remove routine\n" ); 13714 for(ii =0;ii<tweak_target_bodySM.size();ii++) 13715 { 13716 GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine(); 13717 gqe->delete_solid_model_entities(tweak_target_bodySM[ii]); 13718 } 13719 13720 if(enable_undo) 13721 CubitUndo::remove_last_undo(); 13722 13723 return CUBIT_FAILURE; 13724 } 13725 all_kept_bodies+=resulting_bodies; 13726 } 13727 } 13728 else 13729 { 13730 DLIList<BodySM*> swept_bodies; 13731 DLIList<BodySM*> swept_doubler_bodySM; 13732 13733 //take the copied_doubler_surface and extrude it along the sweep_direction to create a body 13734 for(z=0;z<copied_doubler_surface.size();z++) 13735 { 13736 DLIList<GeometryEntity*> DLIList_copied_doubler_surface; 13737 DLIList_copied_doubler_surface.append(copied_doubler_surface[z]); 13738 if(gme_ptr->sweep_translational(DLIList_copied_doubler_surface,swept_doubler_bodySM,sweep_direction*0.0001,0.0,0,CUBIT_FALSE,CUBIT_FALSE) == CUBIT_FAILURE || swept_doubler_bodySM.size()==0) 13739 { 13740 PRINT_ERROR( "Command failed at sweep->extrude command\n" ); 13741 for(ii =0;ii<body_convert.size();ii++) 13742 { 13743 GeometryQueryEngine* gqe = body_convert[ii]->get_geometry_query_engine(); 13744 gqe->delete_solid_model_entities(body_convert[ii]); 13745 } 13746 13747 if(enable_undo) 13748 CubitUndo::remove_last_undo(); 13749 13750 return CUBIT_FAILURE; 13751 } 13752 swept_bodies+=swept_doubler_bodySM; 13753 swept_doubler_bodySM.clean_out(); 13754 } 13755 13756 DLIList<BodySM*> united_bodies; 13757 DLIList<BodySM*> separate_bodies; 13758 //if more than one body, unite and split the newly created bodies, if only one body skip this step 13759 //as the unite will fail 13760 if(swept_bodies.size()==1) 13761 { 13762 separate_bodies=swept_bodies; 13763 } 13764 else 13765 { 13766 if(gme_ptr->unite(swept_bodies,united_bodies) == CUBIT_FAILURE || united_bodies.size()==0 ) 13767 { 13768 PRINT_ERROR( "Command failed at unite command\n" ); 13769 13770 if(enable_undo) 13771 CubitUndo::remove_last_undo(); 13772 13773 return CUBIT_FAILURE; 13774 } 13775 13776 if(gme_ptr->split_body(united_bodies[0],separate_bodies) == CUBIT_FAILURE || separate_bodies.size()==0) 13777 { 13778 PRINT_ERROR( "Command failed at separate command\n" ); 13779 13780 if(enable_undo) 13781 CubitUndo::remove_last_undo(); 13782 13783 return CUBIT_FAILURE; 13784 } 13785 } 13786 13787 //create another copy of copied_doubler_surface since copied_doubler_surface is going to be manipulated 13788 DLIList<Surface*> temp_copied_doubler_surface=copied_doubler_surface; 13789 for(z=0;z<separate_bodies.size();z++) 13790 { 13791 //need to grab the newly created surface opposite the user selected one from the thicken function to carry it through for the tweak target 13792 //this will need to be changed to a for loop to account for multiple thickened bodies if we impliment multiple doubler surfaces 13793 DLIList<Surface*> thicken_surfaces; 13794 separate_bodies[z]->surfaces(thicken_surfaces); 13795 13796 //initializing a lot of variables to be used in the next few steps 13797 DLIList<Surface*> master_surface_remove_list; 13798 DLIList <Curve*> thicken_external_curves; 13799 DLIList<Surface*> tweak_target_surface; 13800 DLIList<Surface*> surfaces_to_remove; 13801 13802 //using a centerpoint of the surfaces, I want to find out which surface from the recently swept bodies corresponds to the surface of the body closest the target 13803 //this has to be done because sweep_translational moves the source surface. Thicken on the otherhand does and doesn't based on number of surfaces being thickened. 13804 int y=0; 13805 for(y=0;y<temp_copied_doubler_surface.size();y++) 13806 { 13807 CubitVector doubler_center_pt = temp_copied_doubler_surface[y]->bounding_box().center(); 13808 int r=0; 13809 for(r=0;r<thicken_surfaces.size();r++) 13810 { 13811 CubitVector test_center_pt = thicken_surfaces[r]->bounding_box().center(); 13812 if((test_center_pt-doubler_center_pt).length()<=.000001) 13813 { 13814 tweak_target_surface.append(thicken_surfaces[r]); 13815 surfaces_to_remove.append(temp_copied_doubler_surface[y]); 13816 } 13817 } 13818 } 13819 //remove the manipulated surfaces from the temp_copied_doubler_surface list 13820 temp_copied_doubler_surface-=surfaces_to_remove; 13821 surfaces_to_remove.clean_out(); 13822 13823 //grab all the curves of the doubler 13824 DLIList <Curve*> doubler_external_curves; 13825 DLIList <LoopSM*> doubler_loopSM_list; 13826 for(y=0;y<tweak_target_surface.size();y++) 13827 { 13828 tweak_target_surface[y]->loopsms(doubler_loopSM_list); 13829 } 13830 13831 for(i=0;i<doubler_loopSM_list.size();i++) 13832 { 13833 doubler_loopSM_list[i]->curves(doubler_external_curves); 13834 } 13835 13836 DLIList <Surface*> doubler_surface_for_this_body = thicken_surfaces; 13837 Curve* test_external_curves1 = NULL; 13838 Curve* test_external_curves2 = NULL; 13839 DLIList <LoopSM*> test_loopSM_list; 13840 13841 for(i=0; i < thicken_surfaces.size(); i++) 13842 { 13843 //step through the thickened bodies surfaces 13844 thicken_surfaces[i]->loopsms(test_loopSM_list); 13845 //grabbing the external curve loop from the face and making it a DLIList <RefEdge*> 13846 test_loopSM_list[0]->curves(thicken_external_curves); 13847 13848 int j=0; 13849 for(j=0;j<thicken_external_curves.size();j++) 13850 { 13851 //step through the loop list 13852 test_external_curves1 = thicken_external_curves[j]; 13853 13854 int k=0; 13855 for(k=0; k<doubler_external_curves.size();k++) 13856 { 13857 //while stepping through the doubler plate curves, compare them to the test_loop_list 13858 test_external_curves2 = doubler_external_curves[k]; 13859 13860 if(test_external_curves2 == test_external_curves1) 13861 { 13862 doubler_surface_for_this_body.remove_all_with_value(thicken_surfaces[i]); 13863 break; 13864 } 13865 } 13866 if(test_external_curves2 == test_external_curves1) 13867 { 13868 break; 13869 } 13870 } 13871 13872 thicken_external_curves.clean_out(); 13873 thicken_external_curves.reset(); 13874 test_loopSM_list.clean_out(); 13875 } 13876 13877 //DLIList <BodySM*> tweak_target_bodySM 13878 tweak_target_bodySM.clean_out(); 13879 if(gme_ptr->tweak_target(tweak_target_surface,target_surface,tweak_target_bodySM,extend_flg,limit_plane) == CUBIT_FAILURE || tweak_target_bodySM.size()==0) 13880 { 13881 PRINT_ERROR( "Command failed at Tweak_Target routine\n" ); 13882 for(ii =0;ii<body_convert.size();ii++) 13883 { 13884 GeometryQueryEngine* gqe = body_convert[ii]->get_geometry_query_engine(); 13885 gqe->delete_solid_model_entities(body_convert[ii]); 13886 } 13887 13888 if(enable_undo) 13889 CubitUndo::remove_last_undo(); 13890 13891 return CUBIT_FAILURE; 13892 } 13893 13894 //make note of the doubler_surface and add it to the delete list 13895 master_surface_remove_list+=doubler_surface_for_this_body; 13896 13897 //clean out these DLIList's as they will be used later on 13898 doubler_loopSM_list.clean_out(); 13899 doubler_external_curves.clean_out(); 13900 13901 //refilling DLIList's as needed based on internal_flg 13902 //basically if surfaces share a curve, that surface will be kept so if you don't want the internal surfaces 13903 //create the list without the internal curves and they'll be removed 13904 if(internal_flg==CUBIT_FALSE) 13905 { 13906 int j=0; 13907 for(i=0;i<doubler_surface_for_this_body.size();i++) 13908 { 13909 doubler_surface_for_this_body[i]->loopsms(doubler_loopSM_list); 13910 for(j=0;j<doubler_loopSM_list.size();j++) 13911 { 13912 LoopType loop_type = doubler_loopSM_list[j]->loop_type(); 13913 if(loop_type == LOOP_TYPE_EXTERNAL || 13914 loop_type == LOOP_TYPE_U_PERIODIC || 13915 loop_type == LOOP_TYPE_V_PERIODIC) 13916 { 13917 doubler_loopSM_list[j]->curves(doubler_external_curves); 13918 break; 13919 } 13920 13921 } 13922 doubler_loopSM_list.clean_out(); 13923 } 13924 } 13925 else 13926 { 13927 for(i=0;i<doubler_surface_for_this_body.size();i++) 13928 { 13929 doubler_surface_for_this_body[i]->loopsms(doubler_loopSM_list); 13930 } 13931 for(i=0;i<doubler_loopSM_list.size();i++) 13932 { 13933 doubler_loopSM_list[i]->curves(doubler_external_curves); 13934 } 13935 } 13936 13937 //recreate the thicken_surfaces list based now on the bodies after the tweak_target command 13938 thicken_surfaces.clean_out(); 13939 tweak_target_bodySM[0]->surfaces(thicken_surfaces); 13940 13941 DLIList <Surface*> surfaces_to_keep; 13942 surfaces_to_remove = thicken_surfaces; 13943 DLIList <Curve*> tweak_external_curves; 13944 13945 for(i=0;i<thicken_surfaces.size();i++) 13946 { 13947 thicken_surfaces[i]->loopsms(test_loopSM_list); 13948 //grabs the external curves from face 13949 test_loopSM_list[0]->curves(tweak_external_curves); 13950 13951 int j=0; 13952 for(j=0;j<tweak_external_curves.size();j++) 13953 { 13954 //step through the loop list 13955 test_external_curves1 = tweak_external_curves[j]; 13956 13957 int k=0; 13958 for(k=0; k<doubler_external_curves.size();k++) 13959 { 13960 //while stepping through the doubler plate curves, compare them to the test_loop_list 13961 test_external_curves2 = doubler_external_curves[k]; 13962 13963 if(test_external_curves2 == test_external_curves1) 13964 { 13965 surfaces_to_keep.append(thicken_surfaces[i]); 13966 break; 13967 } 13968 } 13969 if(test_external_curves2 == test_external_curves1) 13970 { 13971 break; 13972 } 13973 } 13974 test_loopSM_list.clean_out(); 13975 tweak_external_curves.clean_out(); 13976 } 13977 13978 if(surfaces_to_keep.size()==0) 13979 { 13980 PRINT_ERROR( "Failed to find and keep tweak_target surfaces\n" ); 13981 for(ii =0;ii<tweak_target_bodySM.size();ii++) 13982 { 13983 GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine(); 13984 gqe->delete_solid_model_entities(tweak_target_bodySM[ii]); 13985 } 13986 13987 if(enable_undo) 13988 CubitUndo::remove_last_undo(); 13989 13990 return CUBIT_FAILURE; 13991 } 13992 13993 //subtract surfaces 13994 surfaces_to_remove -= surfaces_to_keep; 13995 master_surface_remove_list+=surfaces_to_remove; 13996 13997 DLIList<BodySM*> resulting_bodies; 13998 13999 if(gme_ptr->tweak_remove(master_surface_remove_list,resulting_bodies,CUBIT_FALSE) == CUBIT_FAILURE || resulting_bodies.size()==0) 14000 { 14001 PRINT_ERROR( "Command failed at Tweak_Remove routine\n" ); 14002 for(ii =0;ii<tweak_target_bodySM.size();ii++) 14003 { 14004 GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine(); 14005 gqe->delete_solid_model_entities(tweak_target_bodySM[ii]); 14006 } 14007 14008 if(enable_undo) 14009 CubitUndo::remove_last_undo(); 14010 14011 return CUBIT_FAILURE; 14012 } 14013 14014 //all_kept_bodies is a list of bodies that will eventually be passed into finish_sm_op at the end 14015 all_kept_bodies+=resulting_bodies; 14016 } 14017 } 14018 14019 if(preview==CUBIT_FALSE) 14020 { 14021 DLIList<BodySM*> bodies_to_unite; 14022 //check to see if their is only one body. If only one body skip over the unite and split because 14023 //the unite command will fail (there is a check at the beginning to return cubit_failure) 14024 //append the original doubler surfaces to the resulting body list 14025 14026 for(i=0;i<doubler_surface.size();i++) 14027 { 14028 all_kept_bodies.insert_first(doubler_surface[i]->bodysm()); 14029 } 14030 if(all_kept_bodies.size()!=1) 14031 { 14032 if(gme_ptr->unite(all_kept_bodies,bodies_to_unite) == CUBIT_FAILURE || bodies_to_unite.size()==0 ) 14033 { 14034 PRINT_ERROR( "Command failed at unite command\n" ); 14035 14036 if(enable_undo) 14037 CubitUndo::remove_last_undo(); 14038 14039 return CUBIT_FAILURE; 14040 } 14041 all_kept_bodies.clean_out(); 14042 if(gme_ptr->split_body(bodies_to_unite[0],all_kept_bodies) == CUBIT_FAILURE || all_kept_bodies.size()==0) 14043 { 14044 PRINT_ERROR( "Command failed at separate command\n" ); 14045 14046 if(enable_undo) 14047 CubitUndo::remove_last_undo(); 14048 14049 return CUBIT_FAILURE; 14050 } 14051 } 14052 else 14053 { 14054 PRINT_WARNING( "Command may have failed at finding doubler surface(s) and appending them to the drop-down surfaces\n" ); 14055 14056 if(enable_undo) 14057 CubitUndo::remove_last_undo(); 14058 14059 return CUBIT_FAILURE; 14060 } 14061 14062 //update DAG 14063 CubitStatus stat; 14064 stat = finish_sm_op( old_body_list, all_kept_bodies ,body_list_out ); 14065 if (CUBIT_SUCCESS != stat) { 14066 PRINT_ERROR("GeometryModifyTool::finish_sm_op failed.\n"); 14067 return stat; 14068 } 14069 if(enable_undo) 14070 CubitUndo::note_result_bodies(body_list_out); 14071 14072 return CUBIT_SUCCESS; 14073 } 14074 else 14075 { 14076 DLIList<Curve*> kept_curves; 14077 for(i =0;i<all_kept_bodies.size();i++) 14078 { 14079 all_kept_bodies[i]->curves(kept_curves); 14080 } 14081 14082 GfxPreview::clear(); 14083 14084 for(i=0; i<kept_curves.size();i++) 14085 { 14086 CubitStatus result; 14087 GMem g_mem; 14088 14089 // get the graphics 14090 result = kept_curves[i]->get_geometry_query_engine()-> 14091 get_graphics( kept_curves[i], &g_mem ); 14092 14093 if (result==CUBIT_FAILURE || g_mem.pointListCount == 0) 14094 { 14095 PRINT_WARNING("Unable to preview a curve\n" );; 14096 double len = kept_curves[i]-> 14097 length_from_u(kept_curves[i]->start_param(),kept_curves[i]->end_param()); 14098 14099 PRINT_WARNING("Curve len: %f\n",len); 14100 } 14101 14102 // Draw the polyline 14103 GfxPreview::draw_polyline( g_mem.point_list(), g_mem.pointListCount, CUBIT_BLUE_INDEX ); 14104 } 14105 GfxPreview::flush(); 14106 for(ii =0;ii<tweak_target_bodySM.size();ii++) 14107 { 14108 GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine(); 14109 gqe->delete_solid_model_entities(tweak_target_bodySM[ii]); 14110 } 14111 14112 if(enable_undo) 14113 CubitUndo::note_result_bodies(body_list_out); 14114 14115 return CUBIT_SUCCESS; 14116 } 14117 } 14118 14119 //============================================================================= 14120 // Function : tweak_bend 14121 // Member Type: PUBLIC 14122 // Description: Bend solid bodies based on a bend radius and angle 14123 // Author : Sam Showman 14124 // Date : 06/23/08 14125 //============================================================================= 14126 CubitStatus GeometryModifyTool::tweak_bend( DLIList<Body*> &bend_bodies, 14127 DLIList<Body*> &new_body_list, 14128 CubitVector& neutral_root, 14129 CubitVector& bend_axis, 14130 CubitVector& bend_direction, 14131 double radius, 14132 double angle, 14133 DLIList<CubitVector>& bend_regions, 14134 double width, 14135 CubitBoolean center_bend, 14136 int num_points, 14137 CubitBoolean keep_old_body, 14138 CubitBoolean preview ) 14139 { 14140 if (CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE) 14141 { 14142 if (keep_old_body) 14143 CubitUndo::save_state(); 14144 else 14145 CubitUndo::save_state_with_cubit_file( bend_bodies ); 14146 } 14147 14148 DLIList<BodySM*> new_body_sm_list; 14149 DLIList<BodySM*> bend_bodies_sm; 14150 GeometryModifyEngine* engine; 14151 engine = common_modify_engine(bend_bodies, bend_bodies_sm); 14152 14153 if (!preview) 14154 { 14155 //do_attribute_setup(); 14156 //push_attributes_before_modify(bend_bodies_sm); 14157 } 14158 14159 CubitStatus result = engine->tweak_bend( 14160 bend_bodies_sm, 14161 new_body_sm_list, 14162 neutral_root, 14163 bend_axis, 14164 bend_direction, 14165 radius, 14166 angle, 14167 bend_regions, 14168 width, 14169 center_bend, 14170 num_points, 14171 keep_old_body, 14172 preview); 14173 14174 if (result == CUBIT_FAILURE) 14175 { 14176 if (!preview) 14177 { 14178 //remove_pushed_attributes(bend_bodies_sm, bend_bodies); 14179 //do_attribute_cleanup(); 14180 } 14181 if (CubitUndo::get_undo_enabled()) 14182 CubitUndo::remove_last_undo(); 14183 return CUBIT_FAILURE; 14184 } 14185 14186 if (preview == CUBIT_FALSE) 14187 { 14188 //restore_vg_after_modify(new_body_sm_list, bend_bodies, engine); 14189 //remove_pushed_attributes(new_body_sm_list, bend_bodies); 14190 14191 // Update DAG 14192 CubitStatus stat = finish_sm_op( bend_bodies, new_body_sm_list, new_body_list ); 14193 if (CubitUndo::get_undo_enabled()) 14194 { 14195 if (stat == CUBIT_SUCCESS) 14196 CubitUndo::note_result_bodies( new_body_list ); 14197 else 14198 CubitUndo::remove_last_undo(); 14199 } 14200 14201 //do_attribute_cleanup(); 14202 14203 // Update graphics 14204 /* 14205 bend_bodies.reset(); 14206 int i = 0; 14207 for (i = 0; i < bend_bodies.size(); i++) 14208 { 14209 Body* body_ptr = bend_bodies.get_and_step(); 14210 body_ptr->notify_all_observers( GEOMETRY_MODIFIED ); 14211 }//*/ 14212 14213 // get list of entities to update 14214 DLIList<RefEntity*> entities_to_update; 14215 int i; 14216 for(i=0; i < new_body_sm_list.size(); i++) 14217 { 14218 BodySM* bodysm = new_body_sm_list.get_and_step(); 14219 DLIList<TopologyBridge*> to_check; 14220 DLIList<TopologyBridge*> tmp; 14221 DLIList<Surface*> surfs; 14222 bodysm->surfaces(surfs); 14223 DLIList<Curve*> curves; 14224 bodysm->curves(curves); 14225 DLIList<TBPoint*> points; 14226 bodysm->points(points); 14227 to_check.append(bodysm); 14228 to_check.append(bodysm->lump()); 14229 CAST_LIST_TO_PARENT(surfs, tmp); 14230 to_check += tmp; 14231 CAST_LIST_TO_PARENT(curves, tmp); 14232 to_check += tmp; 14233 CAST_LIST_TO_PARENT(points, tmp); 14234 to_check += tmp; 14235 14236 int k; 14237 for(k=0; k<to_check.size(); k++) 14238 if(BridgeManager* m = to_check.get_and_step()->bridge_manager()) 14239 if(TopologyEntity* t = m->topology_entity()) 14240 entities_to_update.append(CAST_TO(t, RefEntity)); 14241 14242 } 14243 // Update graphics 14244 while (entities_to_update.size()) 14245 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, entities_to_update.pop())); 14246 14247 return stat; 14248 } 14249 14250 return CUBIT_SUCCESS; 14251 } 14252 14253 14254 14255 //============================================================================= 14256 // Description: Chamfer curves on solid and sheet bodies. The left and right 14257 // offsets are with respect to the curve direction. If the given 14258 // right offset is negative, the left offset is used. Users can 14259 // preview to clarify the meaning of left and right. 14260 // Author : Steve Storm 14261 // Date : 03/25/05 14262 //============================================================================= 14263 CubitStatus GeometryModifyTool::tweak_chamfer( DLIList<RefEdge*> &ref_edge_list, 14264 double left_offset, 14265 DLIList<Body*> &new_body_list, 14266 double right_offset, 14267 CubitBoolean keep_old_body, 14268 CubitBoolean preview ) 14269 { 14270 DLIList<Curve*> curve_list(ref_edge_list.size()); 14271 DLIList<Body*> old_body_list; 14272 GeometryModifyEngine* gme_ptr; 14273 14274 gme_ptr = tweak_setup( ref_edge_list, "Chamfering", old_body_list, curve_list, CUBIT_TRUE ); 14275 if( !gme_ptr ) 14276 return CUBIT_FAILURE; 14277 14278 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 14279 { 14280 if( keep_old_body ) 14281 CubitUndo::save_state(); 14282 else 14283 CubitUndo::save_state_with_cubit_file( ref_edge_list ); 14284 } 14285 14286 DLIList<BodySM*> body_sms; 14287 for(int i=old_body_list.size(); i--;) 14288 { 14289 BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr(); 14290 if(bsm) 14291 body_sms.append_unique(bsm); 14292 } 14293 14294 if(!preview) 14295 { 14296 do_attribute_setup(); 14297 push_attributes_before_modify(body_sms); 14298 } 14299 14300 // Do chamfering 14301 DLIList<BodySM*> new_bodysm_list; 14302 CubitStatus stat = gme_ptr->tweak_chamfer( curve_list, left_offset, new_bodysm_list, 14303 right_offset, keep_old_body, preview ); 14304 if(stat == CUBIT_FAILURE ) 14305 { 14306 if(!preview) 14307 { 14308 if( CubitUndo::get_undo_enabled() ) 14309 CubitUndo::remove_last_undo(); 14310 remove_pushed_attributes(new_bodysm_list, old_body_list); 14311 do_attribute_cleanup(); 14312 } 14313 return stat; 14314 } 14315 else 14316 { 14317 if(!preview) 14318 { 14319 restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr); 14320 remove_pushed_attributes(new_bodysm_list, old_body_list); 14321 } 14322 } 14323 14324 if( preview == CUBIT_FALSE ) 14325 { 14326 // Update DAG 14327 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 14328 14329 if( CubitUndo::get_undo_enabled() ) 14330 { 14331 if( stat == CUBIT_SUCCESS ) 14332 CubitUndo::note_result_bodies( new_body_list ); 14333 else 14334 CubitUndo::remove_last_undo(); 14335 } 14336 do_attribute_cleanup(); 14337 14338 return stat; 14339 } 14340 return CUBIT_SUCCESS; 14341 } 14342 14343 void GeometryModifyTool::propagate_from_small_edge(RefEdge *edge, 14344 DLIList<RefEdge*> &small_edges, 14345 DLIList<RefFace*> &narrow_faces, 14346 DLIList<RefFace*> &processed_faces, 14347 double small_edge_length) 14348 { 14349 int i, j; 14350 // First find any small edges connected to this edge. 14351 DLIList<RefVertex*> edge_verts; 14352 edge->ref_vertices(edge_verts); 14353 for(i=edge_verts.size(); i--;) 14354 { 14355 RefVertex *vert = edge_verts.get_and_step(); 14356 DLIList<RefEdge*> vert_edges; 14357 vert->ref_edges(vert_edges); 14358 for(j=vert_edges.size(); j--;) 14359 { 14360 RefEdge *cur_edge = vert_edges.get_and_step(); 14361 if(cur_edge != edge && !cur_edge->marked()) 14362 { 14363 // Mark of > 0 means it has been processed. 14364 cur_edge->marked(1); 14365 if(cur_edge->get_arc_length() < small_edge_length) 14366 { 14367 small_edges.append(cur_edge); 14368 // Mark of 2 means it is a small edge. 14369 cur_edge->marked(2); 14370 propagate_from_small_edge(cur_edge, small_edges, narrow_faces, 14371 processed_faces, small_edge_length); 14372 } 14373 } 14374 } 14375 } 14376 // Now look at adjacent narrow faces and recursively process them. 14377 DLIList<RefFace*> edge_faces; 14378 edge->ref_faces(edge_faces); 14379 for(i=edge_faces.size(); i--;) 14380 { 14381 RefFace *cur_face = edge_faces.get_and_step(); 14382 if(!cur_face->marked()) 14383 { 14384 cur_face->marked(1); 14385 if(GeomMeasureTool::narrow_region_exists(cur_face, small_edge_length)) 14386 { 14387 DLIList<CubitVector> split_pos1_list; 14388 DLIList<CubitVector> split_pos2_list; 14389 GeomMeasureTool::find_split_points_for_narrow_regions(cur_face, 14390 small_edge_length, split_pos1_list, split_pos2_list); 14391 if(split_pos1_list.size() == 0) 14392 { 14393 narrow_faces.append_unique(cur_face); 14394 propagate_over_narrow_face(cur_face, edge, processed_faces, 14395 small_edges, narrow_faces, small_edge_length); 14396 } 14397 } 14398 } 14399 } 14400 } 14401 14402 void GeometryModifyTool::propagate_over_narrow_face(RefFace *narrow_face, 14403 RefEdge *edge, 14404 DLIList<RefFace*> &processed_faces, 14405 DLIList<RefEdge*> &small_edges, 14406 DLIList<RefFace*> &narrow_faces, 14407 double small_edge_length) 14408 { 14409 int i, j; 14410 processed_faces.append(narrow_face); 14411 DLIList<RefEdge*> face_edges; 14412 narrow_face->ref_edges(face_edges); 14413 for(i=face_edges.size(); i--;) 14414 { 14415 RefEdge *cur_edge = face_edges.get_and_step(); 14416 if(cur_edge != edge && !cur_edge->marked()) 14417 { 14418 cur_edge->marked(1); 14419 if(cur_edge->get_arc_length() < small_edge_length) 14420 { 14421 cur_edge->marked(2); 14422 small_edges.append(cur_edge); 14423 propagate_from_small_edge(cur_edge, small_edges, 14424 narrow_faces, processed_faces, small_edge_length); 14425 } 14426 else 14427 { 14428 DLIList<RefFace*> edge_faces; 14429 cur_edge->ref_faces(edge_faces); 14430 for(j=edge_faces.size(); j--;) 14431 { 14432 RefFace *cur_face = edge_faces.get_and_step(); 14433 if(cur_face != narrow_face) 14434 { 14435 if(!cur_face->marked()) 14436 { 14437 cur_face->marked(1); 14438 if(GeomMeasureTool::narrow_region_exists(cur_face, small_edge_length)) 14439 { 14440 DLIList<CubitVector> split_pos1_list; 14441 DLIList<CubitVector> split_pos2_list; 14442 GeomMeasureTool::find_split_points_for_narrow_regions(cur_face, 14443 small_edge_length, split_pos1_list, split_pos2_list); 14444 if(split_pos1_list.size() == 0) 14445 { 14446 narrow_faces.append_unique(cur_face); 14447 propagate_over_narrow_face(cur_face, edge, processed_faces, 14448 small_edges, narrow_faces, small_edge_length); 14449 } 14450 } 14451 } 14452 } 14453 } 14454 } 14455 } 14456 } 14457 } 14458 14459 void GeometryModifyTool::push_tolerance_attribute(DLIList<Body*> &body_list) 14460 { 14461 Body* local_body; 14462 DLIList<RefEntity*> child_list; 14463 14464 //save attribute settings 14465 CGMApp::instance()->save_current_attribute_states(); 14466 14467 CGMApp::instance()->attrib_manager()->auto_flag(0); 14468 CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_ENTITY_TOL, CUBIT_TRUE); 14469 14470 for (int i = body_list.size(); i--;) 14471 { 14472 child_list.clean_out(); 14473 14474 local_body = body_list.get_and_step(); 14475 local_body->get_all_child_ref_entities( child_list); 14476 child_list.append(local_body); 14477 CubitAttribUser::auto_update_cubit_attrib( child_list ); 14478 } 14479 } 14480 14481 void GeometryModifyTool::propagate_merge_tolerance(DLIList<Body*> &body_list) 14482 { 14483 // For each body 14484 // get a list of all children that have a local tolerance 14485 // iterate over that list 14486 // for each entity, get a list of all of its children 14487 // if the parent's tolerance is > child tolerance && the child isn't in the owner_set list 14488 // then set the child's tolerance to the parent's tolerance 14489 14490 DLIList<RefEntity*> owner_set_tolerance_list; 14491 DLIList<RefEntity*> entity_list; 14492 14493 double parent_tolerance = 0.0; 14494 14495 for (int i=body_list.size(); i--;) 14496 { 14497 Body* local_body = body_list.get_and_step(); 14498 14499 // First, get all the children for this body. Save those that already have 14500 // a local tolerance set 14501 local_body->get_all_child_ref_entities(entity_list); 14502 for (int i = entity_list.size(); i--;) 14503 { 14504 RefEntity* local_entity = entity_list.get_and_step(); 14505 if (local_entity->local_tolerance() > 0.0) 14506 owner_set_tolerance_list.append(local_entity); 14507 } 14508 14509 // for each entity in the owner_set list, get all of its children 14510 for (int i = owner_set_tolerance_list.size(); i--;) 14511 { 14512 RefEntity* local_entity = owner_set_tolerance_list.get_and_step(); 14513 parent_tolerance = local_entity->local_tolerance(); 14514 14515 entity_list.clean_out(); 14516 local_entity->get_all_child_ref_entities(entity_list); 14517 for (int j = entity_list.size(); j--;) 14518 { 14519 RefEntity* child_entity = entity_list.get_and_step(); 14520 if (!owner_set_tolerance_list.is_in_list(child_entity)) 14521 { 14522 if (child_entity->local_tolerance() < parent_tolerance) 14523 child_entity->local_tolerance(parent_tolerance); 14524 } 14525 } 14526 } 14527 } 14528 } 14529 14530 CubitStatus GeometryModifyTool::remove_topology( DLIList<RefEdge*> &ref_edge_list, 14531 DLIList<RefFace*> &ref_face_list, 14532 double backoff_distance, 14533 double small_curve_size, 14534 DLIList<Body*> &new_body_list, 14535 CubitBoolean propagate, 14536 CubitBoolean preview) 14537 { 14538 int i, j; 14539 CubitStatus ret = CUBIT_SUCCESS; 14540 DLIList<Surface*> surf_list; 14541 DLIList<Curve*> curve_list; 14542 DLIList<Body*> old_body_list; 14543 GeometryModifyEngine *gme_ptr1=NULL, *gme_ptr2=NULL, *gme_ptr=NULL; 14544 Body *b1=NULL, *b2=NULL, *b=NULL; 14545 14546 if(ref_edge_list.size()) 14547 b1 = ref_edge_list.get()->body(); 14548 if(ref_face_list.size()) 14549 b2 = ref_face_list.get()->body(); 14550 14551 if(b1 && b2) 14552 { 14553 if(b1 == b2) 14554 b = b1; 14555 } 14556 else if(b1) 14557 b = b1; 14558 else if(b2) 14559 b = b2; 14560 14561 if(b) 14562 old_body_list.append(b); 14563 else 14564 { 14565 PRINT_ERROR("Failed to find an owning body for the topology being removed.\n"); 14566 ret = CUBIT_FAILURE; 14567 } 14568 14569 if(ret == CUBIT_SUCCESS) 14570 { 14571 if (!okay_to_modify( old_body_list, "REMOVE_TOPOLOGY" )) 14572 ret = CUBIT_FAILURE; 14573 else 14574 { 14575 // Remove any edges from the list that aren't small enough. 14576 DLIList<RefEdge*> edges_to_remove; 14577 for(i=ref_edge_list.size(); i--;) 14578 { 14579 RefEdge* re = ref_edge_list.get_and_step(); 14580 if(re->get_arc_length() > small_curve_size) 14581 { 14582 edges_to_remove.append(re); 14583 PRINT_INFO("Ignoring curve %d as it is not a small curve based on the input. " 14584 "Try a larger small_curve_size value.\n", re->id()); 14585 } 14586 } 14587 ref_edge_list -= edges_to_remove; 14588 14589 // Remove any faces from the list that don't have at least one small edge. 14590 DLIList<RefFace*> faces_to_remove; 14591 for(i=ref_face_list.size(); i--;) 14592 { 14593 DLIList<RefEdge*> face_edges; 14594 RefFace* rf = ref_face_list.get_and_step(); 14595 rf->ref_edges(face_edges); 14596 int face_ok = 0; 14597 for(j=face_edges.size(); j && !face_ok; j--) 14598 { 14599 RefEdge* cur_edge = face_edges.get_and_step(); 14600 if(cur_edge->get_arc_length() <= small_curve_size) 14601 face_ok = 1; 14602 } 14603 if(!face_ok) 14604 { 14605 faces_to_remove.append(rf); 14606 PRINT_INFO("Ignoring surface %d as it does not have at least one small curve in it based on the input. " 14607 "Try a larger small_curve_size value.\n", rf->id()); 14608 } 14609 } 14610 ref_face_list -= faces_to_remove; 14611 } 14612 14613 if(ref_face_list.size() > 0 || ref_edge_list.size() > 0) 14614 { 14615 // If told to do so propagate the topology to be removed to include 14616 // other narrow surfaces and small edges. 14617 if(propagate) 14618 { 14619 // Get all of the small edges into a single list. 14620 DLIList<RefEdge*> small_edges = ref_edge_list; 14621 for(i=ref_face_list.size(); i--;) 14622 { 14623 RefFace *face = ref_face_list.get_and_step(); 14624 DLIList<RefEdge*> edges; 14625 face->ref_edges(edges); 14626 for(j=edges.size(); j--;) 14627 { 14628 RefEdge *edge = edges.get_and_step(); 14629 if(edge->get_arc_length() < small_curve_size) 14630 small_edges.append(edge); 14631 } 14632 } 14633 small_edges.uniquify_ordered(); 14634 14635 DLIList<RefFace*> processed_faces; 14636 DLIList<RefEdge*> copy_of_small_edges = small_edges; 14637 DLIList<RefFace*> narrow_faces; 14638 14639 DLIList<RefFace*> all_faces; 14640 DLIList<RefEdge*> all_edges; 14641 14642 // Set all of the marked flags to 0. 14643 b->ref_faces(all_faces); 14644 for(i=all_faces.size(); i>0; i--) 14645 all_faces.get_and_step()->marked(0); 14646 14647 b->ref_edges(all_edges); 14648 for(i=all_edges.size(); i>0; i--) 14649 all_edges.get_and_step()->marked(0); 14650 14651 // Mark of >0 means it has been processed. 14652 // Mark of 2 means it is a small edge. 14653 for(i=small_edges.size(); i>0; i--) 14654 small_edges.get_and_step()->marked(2); 14655 14656 // First look at all of the edges connected to small edges 14657 // to see if there are other small edges. 14658 while(copy_of_small_edges.size()) 14659 { 14660 RefEdge *edge = copy_of_small_edges.extract(); 14661 propagate_from_small_edge(edge, small_edges, 14662 narrow_faces, processed_faces, small_curve_size); 14663 } 14664 14665 ref_face_list += narrow_faces; 14666 ref_face_list.uniquify_ordered(); 14667 14668 ref_edge_list = small_edges; 14669 ref_edge_list.uniquify_ordered(); 14670 // Append to face list here so we don't lose the ones that were passed in. 14671 } 14672 } 14673 else 14674 { 14675 PRINT_WARNING("No entities to remove.\n"); 14676 ret = CUBIT_FAILURE; 14677 } 14678 } 14679 14680 if(ret == CUBIT_SUCCESS) 14681 { 14682 if(ref_edge_list.size()) 14683 { 14684 for(i=ref_edge_list.size(); i--;) 14685 { 14686 RefEdge *re = ref_edge_list.get_and_step(); 14687 Curve *cur = re->get_curve_ptr(); 14688 DLIList<TopologyBridge*> tmp_curve_list; 14689 GeometryQueryEngine *gqe = cur->get_geometry_query_engine(); 14690 gqe->get_underlying_curves(cur, tmp_curve_list); 14691 if(tmp_curve_list.size() == 0) 14692 tmp_curve_list.append(cur); 14693 for(int p=tmp_curve_list.size(); p--;) 14694 { 14695 Curve *crv = dynamic_cast<Curve*>(tmp_curve_list.get_and_step()); 14696 if(!gme_ptr1) 14697 gme_ptr1 = get_engine(crv); 14698 curve_list.append(crv); 14699 } 14700 } 14701 } 14702 if(ref_face_list.size()) 14703 { 14704 for(i=ref_face_list.size(); i--;) 14705 { 14706 RefFace *rf = ref_face_list.get_and_step(); 14707 Surface *sur = rf->get_surface_ptr(); 14708 DLIList<TopologyBridge*> tmp_surf_list; 14709 GeometryQueryEngine *gqe = sur->get_geometry_query_engine(); 14710 gqe->get_underlying_surfaces(sur, tmp_surf_list); 14711 if(tmp_surf_list.size() == 0) 14712 tmp_surf_list.append(sur); 14713 for(int p=tmp_surf_list.size(); p--;) 14714 { 14715 Surface *srf = dynamic_cast<Surface*>(tmp_surf_list.get_and_step()); 14716 if(!gme_ptr2) 14717 gme_ptr2 = get_engine(srf); 14718 surf_list.append(srf); 14719 } 14720 } 14721 } 14722 if(gme_ptr1 && gme_ptr2) 14723 { 14724 if(gme_ptr1 == gme_ptr2) 14725 gme_ptr = gme_ptr1; 14726 } 14727 else if(gme_ptr1) 14728 gme_ptr = gme_ptr1; 14729 else if(gme_ptr2) 14730 gme_ptr = gme_ptr2; 14731 14732 if(!gme_ptr) 14733 { 14734 PRINT_ERROR("Failed to find a geometry modify engine.\n"); 14735 ret = CUBIT_FAILURE; 14736 } 14737 } 14738 14739 if(ret == CUBIT_SUCCESS) 14740 { 14741 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 14742 { 14743 DLIList<Body*> bodies; 14744 int i; 14745 for( i=ref_face_list.size(); i--; ) 14746 { 14747 RefFace* ref_face = ref_face_list.get_and_step(); 14748 bodies.append( ref_face->body() ); 14749 } 14750 for( i=ref_edge_list.size(); i--; ) 14751 { 14752 RefEdge* ref_edge = ref_edge_list.get_and_step(); 14753 bodies.append( ref_edge->body() ); 14754 } 14755 bodies.uniquify_ordered(); 14756 CubitUndo::save_state_with_cubit_file( bodies ); 14757 } 14758 14759 if(preview == CUBIT_FALSE) 14760 do_attribute_setup(); 14761 14762 DLIList<BodySM*> body_sm_list(old_body_list.size()); 14763 GeometryModifyEngine* gme = common_modify_engine(old_body_list, body_sm_list); 14764 14765 if(preview == CUBIT_FALSE) 14766 push_attributes_before_modify(body_sm_list); 14767 14768 DLIList<BodySM*> new_bodysm_list; 14769 if(gme_ptr->remove_topology(curve_list, surf_list, backoff_distance, small_curve_size, 14770 new_bodysm_list, preview) == CUBIT_FAILURE) 14771 { 14772 if( CubitUndo::get_undo_enabled() ) 14773 CubitUndo::remove_last_undo(); 14774 14775 if(!preview) 14776 remove_pushed_attributes(new_bodysm_list, old_body_list); 14777 14778 ret = CUBIT_FAILURE; 14779 } 14780 else 14781 { 14782 if( preview == CUBIT_FALSE ) 14783 { 14784 restore_vg_after_modify(new_bodysm_list, old_body_list, gme); 14785 remove_pushed_attributes(new_bodysm_list, old_body_list); 14786 14787 // Update DAG 14788 ret = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 14789 14790 if( CubitUndo::get_undo_enabled() ) 14791 { 14792 if( ret == CUBIT_FAILURE) 14793 CubitUndo::remove_last_undo(); 14794 else 14795 CubitUndo::note_result_bodies( new_body_list ); 14796 } 14797 } 14798 } 14799 14800 if(preview == CUBIT_FALSE) 14801 do_attribute_cleanup(); 14802 } 14803 14804 return ret; 14805 } 14806 14807 //============================================================================= 14808 // Description: Chamfer vertices on solid or sheet bodies. On a solid body 14809 // there can be up to 3 offsets; on a sheet body up to 2 offsets. 14810 // The offsets are in the direction of the supplied edges. If 14811 // multiple vertices are supplied, only one offset value is 14812 // allowed and the edges are not used. 14813 // Author : Steve Storm 14814 // Date : 03/25/05 14815 //============================================================================= 14816 CubitStatus 14817 GeometryModifyTool::tweak_chamfer( DLIList<RefVertex*> &ref_vertex_list, 14818 double offset1, 14819 DLIList<Body*> &new_body_list, 14820 RefEdge *edge1, 14821 double offset2, 14822 RefEdge *edge2, 14823 double offset3, 14824 RefEdge *edge3, 14825 CubitBoolean keep_old_body, 14826 CubitBoolean preview ) 14827 { 14828 if( offset1 <= 0.0 ) 14829 { 14830 PRINT_ERROR( "Chamfer radius not specified.\n" ); 14831 return CUBIT_FAILURE; 14832 } 14833 14834 DLIList<TBPoint*> point_list(ref_vertex_list.size()); 14835 DLIList<Body*> old_body_list; 14836 GeometryModifyEngine* gme_ptr; 14837 14838 gme_ptr = tweak_setup( ref_vertex_list, "Chamfering", old_body_list, point_list, CUBIT_TRUE ); 14839 if( !gme_ptr ) 14840 return CUBIT_FAILURE; 14841 14842 RefVertex *ref_vertex_ptr = ref_vertex_list.get(); 14843 if( ref_vertex_list.size() == 1 && (edge1 || edge2 || edge3) ) 14844 { 14845 // Make sure input edges are attached to the input vertex 14846 DLIList<RefEdge*> ref_edge_list; 14847 ref_vertex_ptr->ref_edges( ref_edge_list ); 14848 14849 if( edge1 && !ref_edge_list.is_in_list( edge1 ) ) 14850 { 14851 PRINT_ERROR( "Specified curve %d not attached to vertex %d\n", edge1->id(), 14852 ref_vertex_ptr->id() ); 14853 return CUBIT_FAILURE; 14854 } 14855 14856 if( edge2 && !ref_edge_list.is_in_list( edge2 ) ) 14857 { 14858 PRINT_ERROR( "Specified curve %d not attached to vertex %d\n", edge1->id(), 14859 ref_vertex_ptr->id() ); 14860 return CUBIT_FAILURE; 14861 } 14862 14863 if( edge3 && !ref_edge_list.is_in_list( edge3 ) ) 14864 { 14865 PRINT_ERROR( "Specified curve %d not attached to vertex %d\n", edge1->id(), 14866 ref_vertex_ptr->id() ); 14867 return CUBIT_FAILURE; 14868 } 14869 14870 // Make sure offsets supplied 14871 if( edge1 && offset1 < 0.0 ) 14872 { 14873 PRINT_ERROR( "Offset for curve %d specified incorrectly.\n", edge1->id() ); 14874 return CUBIT_FAILURE; 14875 } 14876 14877 if( edge2 && offset2 < 0.0 ) 14878 { 14879 PRINT_ERROR( "Offset for curve %d specified incorrectly.\n", edge2->id() ); 14880 return CUBIT_FAILURE; 14881 } 14882 14883 if( edge3 && offset3 < 0.0 ) 14884 { 14885 PRINT_ERROR( "Offset for curve %d specified incorrectly.\n", edge3->id() ); 14886 return CUBIT_FAILURE; 14887 } 14888 } 14889 14890 if( point_list.size() > 1 && offset2 > 0.0 ) 14891 { 14892 PRINT_ERROR( "Cannot supply multiple radii when chamfering multiple vertices.\n" ); 14893 return CUBIT_FAILURE; 14894 } 14895 14896 Curve *curve1 = NULL; 14897 Curve *curve2 = NULL; 14898 Curve *curve3 = NULL; 14899 14900 if( edge1 ) 14901 { 14902 TopologyBridge* bridge = 0; 14903 GeometryModifyEngine* edge_gme = get_engine(edge1, &bridge); 14904 if( gme_ptr != edge_gme ) 14905 { 14906 PRINT_ERROR( "Specified curve %d must belong to same geometry engine as vertex %d.\n", 14907 edge1->id(), ref_vertex_ptr->id() ); 14908 return CUBIT_FAILURE; 14909 } 14910 curve1 = dynamic_cast<Curve*>(bridge); 14911 } 14912 14913 if( edge2 ) 14914 { 14915 TopologyBridge* bridge = 0; 14916 GeometryModifyEngine* edge_gme = get_engine(edge2, &bridge); 14917 if( gme_ptr != edge_gme ) 14918 { 14919 PRINT_ERROR( "Specified curve %d must belong to same geometry engine as vertex %d.\n", 14920 edge2->id(), ref_vertex_ptr->id() ); 14921 return CUBIT_FAILURE; 14922 } 14923 curve2 = dynamic_cast<Curve*>(bridge); 14924 } 14925 14926 if( edge3 ) 14927 { 14928 TopologyBridge* bridge = 0; 14929 GeometryModifyEngine* edge_gme = get_engine(edge3, &bridge); 14930 if( gme_ptr != edge_gme ) 14931 { 14932 PRINT_ERROR( "Specified curve %d must belong to same geometry engine as vertex %d.\n", 14933 edge3->id(), ref_vertex_ptr->id() ); 14934 return CUBIT_FAILURE; 14935 } 14936 curve3 = dynamic_cast<Curve*>(bridge); 14937 } 14938 14939 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 14940 { 14941 if( keep_old_body ) 14942 CubitUndo::save_state(); 14943 else 14944 CubitUndo::save_state_with_cubit_file( ref_vertex_list ); 14945 } 14946 14947 DLIList<BodySM*> body_sms; 14948 for(int i=old_body_list.size(); i--;) 14949 { 14950 BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr(); 14951 if(bsm) 14952 body_sms.append_unique(bsm); 14953 } 14954 14955 if(!preview) 14956 { 14957 do_attribute_setup(); 14958 push_attributes_before_modify(body_sms); 14959 } 14960 14961 // Do chamfering 14962 DLIList<BodySM*> new_bodysm_list; 14963 CubitStatus stat = gme_ptr->tweak_chamfer( point_list, offset1, new_bodysm_list, curve1, offset2, 14964 curve2, offset3, curve3, keep_old_body, preview ); 14965 14966 if(stat == CUBIT_FAILURE) 14967 { 14968 if( CubitUndo::get_undo_enabled() ) 14969 CubitUndo::remove_last_undo(); 14970 if(!preview) 14971 { 14972 remove_pushed_attributes(new_bodysm_list, old_body_list); 14973 do_attribute_cleanup(); 14974 } 14975 return stat; 14976 } 14977 else 14978 { 14979 if(!preview) 14980 { 14981 restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr); 14982 remove_pushed_attributes(new_bodysm_list, old_body_list); 14983 } 14984 } 14985 14986 if( preview == CUBIT_FALSE ) 14987 { 14988 // Update DAG 14989 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 14990 14991 if( CubitUndo::get_undo_enabled() ) 14992 { 14993 if( stat == CUBIT_FAILURE ) 14994 CubitUndo::remove_last_undo(); 14995 else if( keep_old_body ) 14996 CubitUndo::note_result_bodies( new_body_list ); 14997 } 14998 do_attribute_cleanup(); 14999 return stat; 15000 } 15001 15002 return CUBIT_SUCCESS; 15003 } 15004 15005 //============================================================================= 15006 // Description: Create a round fillet (or blend) at the given curves on solid 15007 // or sheet bodies. 15008 // Author : Steve Storm 15009 // Date : 03/25/05 15010 //============================================================================= 15011 CubitStatus GeometryModifyTool::tweak_fillet( DLIList<RefEdge*> &ref_edge_list, 15012 double radius, 15013 DLIList<Body*> &new_body_list, 15014 CubitBoolean keep_old_body, 15015 CubitBoolean preview ) 15016 { 15017 DLIList<Curve*> curve_list(ref_edge_list.size()); 15018 DLIList<Body*> old_body_list; 15019 GeometryModifyEngine* gme_ptr; 15020 15021 gme_ptr = tweak_setup( ref_edge_list, "Filleting", old_body_list, curve_list, CUBIT_TRUE ); 15022 if( !gme_ptr ) 15023 return CUBIT_FAILURE; 15024 15025 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 15026 { 15027 if( keep_old_body ) 15028 CubitUndo::save_state(); 15029 else 15030 CubitUndo::save_state_with_cubit_file( ref_edge_list ); 15031 } 15032 15033 DLIList<BodySM*> body_sms; 15034 for(int i=old_body_list.size(); i--;) 15035 { 15036 BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr(); 15037 if(bsm) 15038 body_sms.append_unique(bsm); 15039 } 15040 15041 if(!preview) 15042 { 15043 do_attribute_setup(); 15044 push_attributes_before_modify(body_sms); 15045 } 15046 15047 // Do filleting 15048 DLIList<BodySM*> new_bodysm_list; 15049 CubitStatus stat = gme_ptr->tweak_fillet(curve_list, radius, new_bodysm_list, keep_old_body, 15050 preview ); 15051 15052 if(stat == CUBIT_FAILURE ) 15053 { 15054 if(!preview) 15055 { 15056 if( CubitUndo::get_undo_enabled() ) 15057 CubitUndo::remove_last_undo(); 15058 remove_pushed_attributes(new_bodysm_list, old_body_list); 15059 do_attribute_cleanup(); 15060 } 15061 return stat; 15062 } 15063 else 15064 { 15065 if(!preview) 15066 { 15067 restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr); 15068 remove_pushed_attributes(new_bodysm_list, old_body_list); 15069 } 15070 } 15071 15072 if( preview == CUBIT_FALSE ) 15073 { 15074 // Update DAG 15075 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 15076 15077 if( CubitUndo::get_undo_enabled() ) 15078 { 15079 if( stat == CUBIT_FAILURE ) 15080 CubitUndo::remove_last_undo(); 15081 else if( keep_old_body ) 15082 CubitUndo::note_result_bodies( new_body_list ); 15083 } 15084 do_attribute_cleanup(); 15085 15086 return stat; 15087 } 15088 return CUBIT_SUCCESS; 15089 } 15090 15091 //============================================================================= 15092 // Description: Create a round fillet (or blend) at the given curves on a solid 15093 // or sheet body. The fillet has a variable radius from the start 15094 // to the end of the curve. 15095 // Author : Steve Storm 15096 // Date : 03/25/05 15097 //============================================================================= 15098 CubitStatus GeometryModifyTool::tweak_fillet( RefEdge *ref_edge_ptr, 15099 double start_radius, 15100 double end_radius, 15101 Body *&new_body_ptr, 15102 CubitBoolean keep_old_body, 15103 CubitBoolean preview ) 15104 { 15105 DLIList<Curve*> curve_list(1); 15106 DLIList<Body*> old_body_list; 15107 GeometryModifyEngine* gme_ptr; 15108 15109 DLIList<RefEdge*> ref_edge_list(1); 15110 ref_edge_list.append( ref_edge_ptr ); 15111 15112 gme_ptr = tweak_setup( ref_edge_list, "Filleting", old_body_list, curve_list, CUBIT_TRUE ); 15113 if( !gme_ptr ) 15114 return CUBIT_FAILURE; 15115 15116 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 15117 { 15118 if( keep_old_body ) 15119 CubitUndo::save_state(); 15120 else 15121 { 15122 DLIList<RefEdge*> edges(1); 15123 edges.append( ref_edge_ptr ); 15124 CubitUndo::save_state_with_cubit_file( edges ); 15125 } 15126 } 15127 15128 DLIList<BodySM*> body_sms; 15129 for(int i=old_body_list.size(); i--;) 15130 { 15131 BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr(); 15132 if(bsm) 15133 body_sms.append_unique(bsm); 15134 } 15135 15136 if(!preview) 15137 { 15138 do_attribute_setup(); 15139 push_attributes_before_modify(body_sms); 15140 } 15141 15142 // Do filleting 15143 BodySM *new_bodysm_ptr; 15144 Curve *curve_ptr = curve_list.get(); 15145 CubitStatus stat = gme_ptr->tweak_fillet( curve_ptr, start_radius, 15146 end_radius, new_bodysm_ptr, 15147 keep_old_body, preview ); 15148 15149 if( CubitUndo::get_undo_enabled() ) 15150 if( stat == CUBIT_FAILURE) 15151 CubitUndo::remove_last_undo(); 15152 15153 DLIList<BodySM*> new_bodysm_list; 15154 new_bodysm_list.append(new_bodysm_ptr); 15155 if( stat == CUBIT_FAILURE ) 15156 { 15157 remove_pushed_attributes(new_bodysm_list, old_body_list); 15158 do_attribute_cleanup(); 15159 return stat; 15160 } 15161 else 15162 { 15163 restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr); 15164 remove_pushed_attributes(new_bodysm_list, old_body_list); 15165 } 15166 15167 if( preview == CUBIT_FALSE ) 15168 { 15169 // Update DAG 15170 DLIList<BodySM*> new_bodysm_list; 15171 new_bodysm_list.append( new_bodysm_ptr ); 15172 DLIList<Body*> new_body_list; 15173 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 15174 15175 if( CubitUndo::get_undo_enabled() ) 15176 { 15177 if( stat == CUBIT_FAILURE ) 15178 CubitUndo::remove_last_undo(); 15179 else if( keep_old_body ) 15180 CubitUndo::note_result_bodies( new_body_list ); 15181 } 15182 15183 new_body_ptr = new_body_list.get(); 15184 15185 do_attribute_cleanup(); 15186 15187 return stat; 15188 } 15189 return CUBIT_SUCCESS; 15190 } 15191 15192 //============================================================================= 15193 // Description: Create a round fillet (or blend) at the given vertices on sheet 15194 // bodies. 15195 // Author : Steve Storm 15196 // Date : 03/25/05 15197 //============================================================================= 15198 CubitStatus 15199 GeometryModifyTool::tweak_fillet( DLIList<RefVertex*> &ref_vertex_list, 15200 double radius, 15201 DLIList<Body*> &new_body_list, 15202 CubitBoolean keep_old_body, 15203 CubitBoolean preview ) 15204 { 15205 DLIList<TBPoint*> point_list(ref_vertex_list.size()); 15206 DLIList<Body*> old_body_list; 15207 GeometryModifyEngine* gme_ptr; 15208 15209 gme_ptr = tweak_setup( ref_vertex_list, "Filleting", old_body_list, point_list, CUBIT_TRUE ); 15210 if( !gme_ptr ) 15211 return CUBIT_FAILURE; 15212 15213 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 15214 { 15215 if( keep_old_body ) 15216 CubitUndo::save_state(); 15217 else 15218 CubitUndo::save_state_with_cubit_file( ref_vertex_list ); 15219 } 15220 15221 DLIList<BodySM*> body_sms; 15222 for(int i=old_body_list.size(); i--;) 15223 { 15224 BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr(); 15225 if(bsm) 15226 body_sms.append_unique(bsm); 15227 } 15228 15229 if(!preview) 15230 { 15231 do_attribute_setup(); 15232 push_attributes_before_modify(body_sms); 15233 } 15234 15235 // Do filleting 15236 DLIList<BodySM*> new_bodysm_list; 15237 CubitStatus stat = gme_ptr->tweak_fillet( point_list, radius, 15238 new_bodysm_list, keep_old_body, 15239 preview ); 15240 if(stat == CUBIT_FAILURE ) 15241 { 15242 if(!preview) 15243 { 15244 if( CubitUndo::get_undo_enabled() ) 15245 CubitUndo::remove_last_undo(); 15246 remove_pushed_attributes(new_bodysm_list, old_body_list); 15247 do_attribute_cleanup(); 15248 } 15249 return stat; 15250 } 15251 else 15252 { 15253 if(!preview) 15254 { 15255 restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr); 15256 remove_pushed_attributes(new_bodysm_list, old_body_list); 15257 } 15258 } 15259 15260 if( preview == CUBIT_FALSE ) 15261 { 15262 // Update DAG 15263 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 15264 15265 if( CubitUndo::get_undo_enabled() ) 15266 { 15267 if( stat == CUBIT_FAILURE ) 15268 CubitUndo::remove_last_undo(); 15269 else if( keep_old_body ) 15270 CubitUndo::note_result_bodies( new_body_list ); 15271 } 15272 15273 do_attribute_cleanup(); 15274 15275 return stat; 15276 } 15277 return CUBIT_SUCCESS; 15278 } 15279 15280 //============================================================================= 15281 // Description: Tweak specified faces of a volume or volumes along a vector. 15282 // Author : Steve Storm 15283 // Date : 03/25/05 15284 //============================================================================= 15285 CubitStatus GeometryModifyTool::tweak_move( DLIList<RefFace*>& ref_face_list, 15286 const CubitVector &delta, 15287 DLIList<Body*>& new_body_list, 15288 CubitBoolean keep_old_body, 15289 CubitBoolean preview ) 15290 { 15291 DLIList<Surface*> surface_list(ref_face_list.size()); 15292 DLIList<Body*> old_body_list; 15293 GeometryModifyEngine* gme_ptr; 15294 15295 gme_ptr = tweak_setup( ref_face_list, "Moving", old_body_list, surface_list, CUBIT_TRUE ); 15296 if (!gme_ptr) 15297 return CUBIT_FAILURE; 15298 15299 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 15300 { 15301 if( keep_old_body ) 15302 CubitUndo::save_state(); 15303 else 15304 { 15305 int i; 15306 DLIList<RefEdge*> ref_edges; 15307 for( i=ref_face_list.size(); i--; ) 15308 ref_face_list.get_and_step()->ref_edges( ref_edges ); 15309 ref_edges.uniquify_unordered(); 15310 CubitUndo::save_state_with_cubit_file( ref_edges ); 15311 } 15312 } 15313 15314 int i; 15315 DLIList<BodySM*> body_sms; 15316 for(i=old_body_list.size(); i--;) 15317 { 15318 BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr(); 15319 if(bsm) 15320 body_sms.append_unique(bsm); 15321 } 15322 15323 if(!preview) 15324 { 15325 do_attribute_setup(); 15326 push_attributes_before_modify(body_sms); 15327 } 15328 15329 // Do move 15330 DLIList<BodySM*> new_bodysm_list; 15331 CubitStatus stat = gme_ptr->tweak_move( surface_list, delta, 15332 new_bodysm_list, keep_old_body, 15333 preview ); 15334 15335 15336 if( CubitUndo::get_undo_enabled() ) 15337 if( stat == CUBIT_FAILURE) 15338 CubitUndo::remove_last_undo(); 15339 15340 if( stat == CUBIT_FAILURE ) 15341 { 15342 if(!preview) 15343 { 15344 remove_pushed_attributes(new_bodysm_list, old_body_list); 15345 do_attribute_cleanup(); 15346 } 15347 return stat; 15348 } 15349 else 15350 { 15351 if(!preview) 15352 { 15353 restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr); 15354 remove_pushed_attributes(new_bodysm_list, old_body_list); 15355 } 15356 } 15357 15358 // loop body sm list and find surfaces that need updating. 15359 // this is to account for some cases where the topology doesn't change, but the geometry does. 15360 DLIList<RefEntity*> entities_to_update; 15361 for(i=0; i<new_bodysm_list.size(); i++) 15362 { 15363 BodySM* bodysm = new_bodysm_list.get_and_step(); 15364 DLIList<Surface*> surfs; 15365 bodysm->surfaces(surfs); 15366 int j; 15367 // find a surface that is also found in our input list 15368 for(j=0; j<surfs.size(); j++, surfs.step()) 15369 { 15370 BridgeManager* man = surfs.get()->bridge_manager(); 15371 if(man) 15372 { 15373 RefFace* ref_face = CAST_TO(man->topology_entity(), RefFace); 15374 if(ref_face && ref_face_list.is_in_list(ref_face)) 15375 { 15376 // get neighbors 15377 DLIList<TBPoint*> neighbor_points; 15378 surfs.get()->points(neighbor_points); 15379 DLIList<Curve*> neighbor_curves; 15380 DLIList<Surface*> neighbor_surfaces; 15381 DLIList<TopologyBridge*> neighbors; 15382 DLIList<TopologyBridge*> tmp; 15383 int k; 15384 for(k=0; k<neighbor_points.size(); k++) 15385 neighbor_points.get_and_step()->surfaces(neighbor_surfaces); 15386 for(k=0; k<neighbor_points.size(); k++) 15387 neighbor_points.get_and_step()->curves(neighbor_curves); 15388 15389 CAST_LIST_TO_PARENT(neighbor_points, tmp); 15390 neighbors += tmp; 15391 neighbor_curves.uniquify_ordered(); 15392 CAST_LIST_TO_PARENT(neighbor_curves, tmp); 15393 neighbors += tmp; 15394 neighbor_surfaces.uniquify_ordered(); 15395 CAST_LIST_TO_PARENT(neighbor_surfaces, tmp); 15396 neighbors += tmp; 15397 neighbors.append(surfs.get()->lump()); 15398 neighbors.append(surfs.get()->bodysm()); 15399 15400 for(k=0; k<neighbors.size(); k++) 15401 if(BridgeManager* m = neighbors.get_and_step()->bridge_manager()) 15402 if(TopologyEntity* t = m->topology_entity()) 15403 entities_to_update.append(CAST_TO(t, RefEntity)); 15404 } 15405 } 15406 } 15407 } 15408 15409 if( preview == CUBIT_FALSE ) 15410 { 15411 // Update DAG 15412 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 15413 15414 if( CubitUndo::get_undo_enabled() ) 15415 { 15416 if( stat == CUBIT_FAILURE ) 15417 CubitUndo::remove_last_undo(); 15418 else if( keep_old_body ) 15419 CubitUndo::note_result_bodies( new_body_list ); 15420 } 15421 15422 // Update graphics 15423 while (entities_to_update.size()) 15424 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, entities_to_update.pop())); 15425 15426 do_attribute_cleanup(); 15427 } 15428 15429 15430 //collect all the new faces 15431 DLIList<RefFace*> new_faces; 15432 for( i=new_body_list.size(); i--; ) 15433 { 15434 Body *new_body = new_body_list.get_and_step(); 15435 DLIList<RefFace*> tmp_faces; 15436 new_body->ref_faces( tmp_faces ); 15437 new_faces += tmp_faces; 15438 } 15439 15440 //unmerge any merged adjacent surfaces or 15441 //merged curves in unmerged adjacent surfaces 15442 DLIList<RefFace*> adjacent_faces_to_unmerge; 15443 DLIList<RefEdge*> adjacent_edges_to_unmerge; 15444 for(i=ref_face_list.size(); i--;) 15445 { 15446 RefFace *tweaked_face = ref_face_list.get_and_step(); 15447 if( !new_faces.move_to( tweaked_face ) ) 15448 continue; 15449 15450 //get all the edges of the face you tweaked 15451 DLIList<RefEdge*> tweaked_face_edges; 15452 tweaked_face->ref_edges( tweaked_face_edges ); 15453 adjacent_edges_to_unmerge += tweaked_face_edges; 15454 15455 //get all the adjacent faces to this edge 15456 int j; 15457 for( j=tweaked_face_edges.size(); j--; ) 15458 { 15459 RefEdge *tmp_edge = tweaked_face_edges.get_and_step(); 15460 DLIList<RefFace*> tmp_faces; 15461 tmp_edge->ref_faces( tmp_faces ); 15462 tmp_faces.remove( tweaked_face ); 15463 adjacent_faces_to_unmerge += tmp_faces; 15464 } 15465 15466 //get all edges not in the surface, 15467 //sharing vertices with the surface 15468 DLIList<RefVertex*> ref_vertices; 15469 tweaked_face->ref_vertices( ref_vertices ); 15470 for( j=ref_vertices.size(); j--; ) 15471 { 15472 RefVertex *tmp_vert = ref_vertices.get_and_step(); 15473 DLIList<RefEdge*> ref_edges; 15474 tmp_vert->ref_edges( ref_edges ); 15475 15476 int k; 15477 for( k=ref_edges.size(); k--; ) 15478 { 15479 RefEdge *tmp_edge = ref_edges.get_and_step(); 15480 if( !tweaked_face_edges.move_to( tmp_edge ) ) 15481 adjacent_edges_to_unmerge.append( tmp_edge ); 15482 } 15483 } 15484 } 15485 15486 //unmerge any adjacent faces 15487 adjacent_faces_to_unmerge.uniquify_unordered(); 15488 for( i=adjacent_faces_to_unmerge.size(); i--; ) 15489 { 15490 RefFace *ref_face = adjacent_faces_to_unmerge.get_and_step(); 15491 15492 DLIList<TopologyBridge*> bridge_list; 15493 ref_face->bridge_manager()->get_bridge_list(bridge_list); 15494 if (bridge_list.size() > 1) 15495 { 15496 if( MergeTool::instance()->unmerge( ref_face ) ) 15497 PRINT_WARNING("Unmerging Surface %d\n", ref_face->id() ); 15498 } 15499 } 15500 15501 //unmerge any adjacent edges 15502 adjacent_edges_to_unmerge.uniquify_unordered(); 15503 for( i=adjacent_edges_to_unmerge.size(); i--; ) 15504 { 15505 RefEdge *ref_edge = adjacent_edges_to_unmerge.get_and_step(); 15506 DLIList<TopologyBridge*> bridge_list; 15507 ref_edge->bridge_manager()->get_bridge_list(bridge_list); 15508 if (bridge_list.size() > 1) 15509 { 15510 if( MergeTool::instance()->unmerge( ref_edge) ) 15511 PRINT_WARNING("Unmerging Curve %d\n", ref_edge->id() ); 15512 } 15513 } 15514 15515 15516 return stat; 15517 } 15518 15519 //============================================================================= 15520 // Description: Tweak specified curves of a sheet body along a vector. 15521 // Author : Steve Storm 15522 // Date : 03/25/05 15523 //============================================================================= 15524 CubitStatus GeometryModifyTool::tweak_move( DLIList<RefEdge*>& ref_edge_list, 15525 const CubitVector &delta, 15526 DLIList<Body*>& new_body_list, 15527 CubitBoolean keep_old_body, 15528 CubitBoolean preview ) 15529 { 15530 DLIList<Curve*> curve_list(ref_edge_list.size()); 15531 DLIList<Body*> old_body_list; 15532 GeometryModifyEngine* gme_ptr; 15533 15534 gme_ptr = tweak_setup( ref_edge_list, "Moving", old_body_list, curve_list ); 15535 if (!gme_ptr) 15536 return CUBIT_FAILURE; 15537 15538 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 15539 { 15540 if( keep_old_body ) 15541 CubitUndo::save_state(); 15542 else 15543 CubitUndo::save_state_with_cubit_file( ref_edge_list ); 15544 } 15545 15546 // Do move 15547 DLIList<BodySM*> new_bodysm_list; 15548 CubitStatus stat = gme_ptr->tweak_move( curve_list, delta, 15549 new_bodysm_list, keep_old_body, 15550 preview ); 15551 15552 if( CubitUndo::get_undo_enabled() ) 15553 if( stat == CUBIT_FAILURE) 15554 CubitUndo::remove_last_undo(); 15555 15556 if( stat == CUBIT_FAILURE ) 15557 return stat; 15558 15559 if( preview == CUBIT_FALSE ) 15560 { 15561 // Update DAG 15562 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 15563 15564 if( CubitUndo::get_undo_enabled() ) 15565 { 15566 if( stat == CUBIT_FAILURE ) 15567 CubitUndo::remove_last_undo(); 15568 else if( keep_old_body ) 15569 CubitUndo::note_result_bodies( new_body_list ); 15570 } 15571 } 15572 15573 // Update graphics 15574 DLIList<Body*> moved_bodies(new_body_list); 15575 moved_bodies.intersect(old_body_list); 15576 while (moved_bodies.size()) 15577 moved_bodies.pop()->notify_sub_all_observers( GeometryEvent::GEOMETRY_MODIFIED ); 15578 15579 return stat; 15580 } 15581 15582 //============================================================================= 15583 // Description: Tweak specified faces of a volume or volumes by offsetting 15584 // those faces by the offset distance. 15585 // Author : Steve Storm 15586 // Date : 03/25/05 15587 //============================================================================= 15588 CubitStatus GeometryModifyTool::tweak_offset( DLIList<RefFace*> &ref_face_list, 15589 double offset_distance, 15590 DLIList<RefFace*> *add_ref_face_list_ptr, 15591 DLIList<double> *add_offset_list_ptr, 15592 DLIList<Body*> &new_body_list, 15593 CubitBoolean keep_old_body, 15594 CubitBoolean preview ) 15595 { 15596 DLIList<RefFace*> all_ref_face_list(ref_face_list.size()); 15597 all_ref_face_list = ref_face_list; 15598 if( add_ref_face_list_ptr->size() ) 15599 all_ref_face_list += *add_ref_face_list_ptr; 15600 15601 DLIList<Surface*> surface_list(ref_face_list.size()); 15602 DLIList<Body*> old_body_list; 15603 GeometryModifyEngine* gme_ptr; 15604 15605 gme_ptr = tweak_setup( ref_face_list, "Offsetting", old_body_list, surface_list, CUBIT_TRUE ); 15606 if (!gme_ptr) 15607 return CUBIT_FAILURE; 15608 15609 DLIList<Surface*> add_surface_list; 15610 if( add_ref_face_list_ptr && add_ref_face_list_ptr->size() ) 15611 { 15612 DLIList<Body*> old_body_list2; 15613 GeometryModifyEngine* gme_ptr2 = tweak_setup( *add_ref_face_list_ptr, "Offsetting", 15614 old_body_list2, add_surface_list, CUBIT_TRUE ); 15615 if (!gme_ptr2) 15616 return CUBIT_FAILURE; 15617 if( gme_ptr != gme_ptr2 ) 15618 { 15619 PRINT_ERROR("Offsetting surfaces on volumes containing surfaces from different\n" 15620 " geometry engines is not allowed.\n"); 15621 return CUBIT_FAILURE; 15622 } 15623 old_body_list.merge_unique( old_body_list2 ); 15624 } 15625 15626 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 15627 { 15628 if( keep_old_body ) 15629 CubitUndo::save_state(); 15630 else 15631 { 15632 int i; 15633 DLIList<RefEdge*> ref_edges; 15634 for( i=ref_face_list.size(); i--; ) 15635 all_ref_face_list.get_and_step()->ref_edges( ref_edges ); 15636 ref_edges.uniquify_unordered(); 15637 CubitUndo::save_state_with_cubit_file( ref_edges ); 15638 } 15639 } 15640 15641 int i; 15642 if(!preview) 15643 { 15644 DLIList<BodySM*> body_sms; 15645 for(i=old_body_list.size(); i--;) 15646 { 15647 BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr(); 15648 if(bsm) 15649 body_sms.append_unique(bsm); 15650 } 15651 15652 do_attribute_setup(); 15653 push_attributes_before_modify(body_sms); 15654 } 15655 15656 // Do offset 15657 DLIList<BodySM*> new_bodysm_list; 15658 CubitStatus stat; 15659 if( add_surface_list.size() ) 15660 stat = gme_ptr->tweak_offset( surface_list, offset_distance, 15661 &add_surface_list, add_offset_list_ptr, 15662 new_bodysm_list, keep_old_body, preview ); 15663 else 15664 stat = gme_ptr->tweak_offset( surface_list, offset_distance, NULL, NULL, 15665 new_bodysm_list, keep_old_body, preview ); 15666 15667 if( CubitUndo::get_undo_enabled() ) 15668 if( stat == CUBIT_FAILURE) 15669 CubitUndo::remove_last_undo(); 15670 15671 if( stat == CUBIT_FAILURE ) 15672 { 15673 if(!preview) 15674 { 15675 remove_pushed_attributes(new_bodysm_list, old_body_list); 15676 do_attribute_cleanup(); 15677 } 15678 return stat; 15679 } 15680 else 15681 { 15682 if(!preview) 15683 { 15684 restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr); 15685 remove_pushed_attributes(new_bodysm_list, old_body_list); 15686 } 15687 } 15688 15689 // Collect all of the old faces to be compared later with the new faces...DJQ 15690 DLIList<RefFace*> old_faces; 15691 for (i = 0; i < old_body_list.size(); i++) 15692 { 15693 Body *old_body = old_body_list.get_and_step(); 15694 DLIList<RefFace*> tmp_faces; 15695 old_body->ref_faces(tmp_faces); 15696 old_faces +=tmp_faces; 15697 } 15698 15699 if( preview == CUBIT_FALSE ) 15700 { 15701 // Update DAG 15702 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 15703 15704 if( CubitUndo::get_undo_enabled() ) 15705 { 15706 if( stat == CUBIT_FAILURE ) 15707 CubitUndo::remove_last_undo(); 15708 else if( keep_old_body ) 15709 CubitUndo::note_result_bodies( new_body_list ); 15710 } 15711 do_attribute_cleanup(); 15712 } 15713 15714 //collect all the new faces 15715 DLIList<RefFace*> new_faces; 15716 for( i=new_body_list.size(); i--; ) 15717 { 15718 Body *new_body = new_body_list.get_and_step(); 15719 DLIList<RefFace*> tmp_faces; 15720 new_body->ref_faces( tmp_faces ); 15721 new_faces += tmp_faces; 15722 } 15723 15724 // Compare the new_faces list with the old_faces list to determine which faces are created 15725 // Add these faces to the all_ref_face_list to check for its neighbors...DJQ 15726 DLIList<RefFace*> difference = new_faces; 15727 difference -= old_faces; 15728 all_ref_face_list += difference; 15729 15730 // loop body sm list and find surfaces that need updating. 15731 // this is to account for some cases where the topology 15732 //doesn't change, but the geometry does. 15733 15734 DLIList<RefEntity*> entities_to_update; 15735 for(i=0; i<new_bodysm_list.size(); i++) 15736 { 15737 BodySM* bodysm = new_bodysm_list.get_and_step(); 15738 DLIList<Surface*> surfs; 15739 bodysm->surfaces(surfs); 15740 int j; 15741 // find a surface that is also found in our input list 15742 for(j=0; j<surfs.size(); j++, surfs.step()) 15743 { 15744 BridgeManager* man = surfs.get()->bridge_manager(); 15745 if(man) 15746 { 15747 RefFace* ref_face = CAST_TO(man->topology_entity(), RefFace); 15748 if(ref_face && all_ref_face_list.is_in_list(ref_face)) 15749 { 15750 // get neighbors 15751 DLIList<TBPoint*> neighbor_points; 15752 surfs.get()->points(neighbor_points); 15753 DLIList<Curve*> neighbor_curves; 15754 DLIList<Surface*> neighbor_surfaces; 15755 DLIList<TopologyBridge*> neighbors; 15756 DLIList<TopologyBridge*> tmp; 15757 int k; 15758 for(k=0; k<neighbor_points.size(); k++) 15759 neighbor_points.get_and_step()->surfaces(neighbor_surfaces); 15760 for(k=0; k<neighbor_points.size(); k++) 15761 neighbor_points.get_and_step()->curves(neighbor_curves); 15762 15763 CAST_LIST_TO_PARENT(neighbor_points, tmp); 15764 neighbors += tmp; 15765 neighbor_curves.uniquify_ordered(); 15766 CAST_LIST_TO_PARENT(neighbor_curves, tmp); 15767 neighbors += tmp; 15768 neighbor_surfaces.uniquify_ordered(); 15769 CAST_LIST_TO_PARENT(neighbor_surfaces, tmp); 15770 neighbors += tmp; 15771 neighbors.append(surfs.get()->lump()); 15772 neighbors.append(surfs.get()->bodysm()); 15773 15774 for(k=0; k<neighbors.size(); k++) 15775 if(BridgeManager* m = neighbors.get_and_step()->bridge_manager()) 15776 if(TopologyEntity* t = m->topology_entity()) 15777 entities_to_update.append(CAST_TO(t, RefEntity)); 15778 } 15779 } 15780 } 15781 } 15782 15783 15784 //unmerge any merged adjacent surfaces or 15785 //merged curves in unmerged adjacent surfaces 15786 DLIList<RefFace*> adjacent_faces_to_unmerge; 15787 DLIList<RefEdge*> adjacent_edges_to_unmerge; 15788 for(i=ref_face_list.size(); i--;) 15789 { 15790 RefFace *tweaked_face = ref_face_list.get_and_step(); 15791 if( !new_faces.move_to( tweaked_face ) ) 15792 continue; 15793 15794 //get all the edges of the face you tweaked 15795 DLIList<RefEdge*> tweaked_face_edges; 15796 tweaked_face->ref_edges( tweaked_face_edges ); 15797 adjacent_edges_to_unmerge += tweaked_face_edges; 15798 15799 //get all the adjacent faces to this edge 15800 int j; 15801 for( j=tweaked_face_edges.size(); j--; ) 15802 { 15803 RefEdge *tmp_edge = tweaked_face_edges.get_and_step(); 15804 DLIList<RefFace*> tmp_faces; 15805 tmp_edge->ref_faces( tmp_faces ); 15806 tmp_faces.remove( tweaked_face ); 15807 adjacent_faces_to_unmerge += tmp_faces; 15808 } 15809 15810 //get all edges not in the surface, 15811 //sharing vertices with the surface 15812 DLIList<RefVertex*> ref_vertices; 15813 tweaked_face->ref_vertices( ref_vertices ); 15814 for( j=ref_vertices.size(); j--; ) 15815 { 15816 RefVertex *tmp_vert = ref_vertices.get_and_step(); 15817 DLIList<RefEdge*> ref_edges; 15818 tmp_vert->ref_edges( ref_edges ); 15819 15820 int k; 15821 for( k=ref_edges.size(); k--; ) 15822 { 15823 RefEdge *tmp_edge = ref_edges.get_and_step(); 15824 if( !tweaked_face_edges.move_to( tmp_edge ) ) 15825 adjacent_edges_to_unmerge.append( tmp_edge ); 15826 } 15827 } 15828 } 15829 15830 //unmerge any adjacent faces 15831 adjacent_faces_to_unmerge.uniquify_unordered(); 15832 for( i=adjacent_faces_to_unmerge.size(); i--; ) 15833 { 15834 RefFace *ref_face = adjacent_faces_to_unmerge.get_and_step(); 15835 15836 DLIList<TopologyBridge*> bridge_list; 15837 ref_face->bridge_manager()->get_bridge_list(bridge_list); 15838 if (bridge_list.size() > 1) 15839 { 15840 if( MergeTool::instance()->unmerge( ref_face ) ) 15841 PRINT_WARNING("Unmerging Surface %d\n", ref_face->id() ); 15842 } 15843 } 15844 15845 //unmerge any adjacent edges 15846 adjacent_edges_to_unmerge.uniquify_unordered(); 15847 for( i=adjacent_edges_to_unmerge.size(); i--; ) 15848 { 15849 RefEdge *ref_edge = adjacent_edges_to_unmerge.get_and_step(); 15850 DLIList<TopologyBridge*> bridge_list; 15851 ref_edge->bridge_manager()->get_bridge_list(bridge_list); 15852 if (bridge_list.size() > 1) 15853 { 15854 if( MergeTool::instance()->unmerge( ref_edge) ) 15855 PRINT_WARNING("Unmerging Curve %d\n", ref_edge->id() ); 15856 } 15857 } 15858 15859 // Update graphics 15860 while (entities_to_update.size()) 15861 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, entities_to_update.pop())); 15862 15863 return stat; 15864 } 15865 15866 //============================================================================= 15867 // Description: Tweak specified curves of a sheet body or bodies by offsetting 15868 // those curves by the offset distance. 15869 // Author : Steve Storm 15870 // Date : 03/25/05 15871 //============================================================================= 15872 CubitStatus GeometryModifyTool::tweak_offset( DLIList<RefEdge*> &ref_edge_list, 15873 double offset_distance, 15874 DLIList<RefEdge*> *add_ref_edge_list_ptr, 15875 DLIList<double> *add_offset_list_ptr, 15876 DLIList<Body*> &new_body_list, 15877 CubitBoolean keep_old_body, 15878 CubitBoolean preview ) 15879 { 15880 DLIList<RefEdge*> all_ref_edge_list(ref_edge_list.size()); 15881 all_ref_edge_list = ref_edge_list; 15882 if( add_ref_edge_list_ptr ) 15883 all_ref_edge_list += *add_ref_edge_list_ptr; 15884 15885 DLIList<Curve*> curve_list(ref_edge_list.size()); 15886 DLIList<Body*> old_body_list; 15887 GeometryModifyEngine* gme_ptr; 15888 15889 gme_ptr = tweak_setup( ref_edge_list, "Offsetting", old_body_list, curve_list ); 15890 if (!gme_ptr) 15891 return CUBIT_FAILURE; 15892 15893 DLIList<Curve*> add_curve_list; 15894 if( add_ref_edge_list_ptr && add_ref_edge_list_ptr->size() ) 15895 { 15896 DLIList<Body*> old_body_list2; 15897 GeometryModifyEngine* gme_ptr2 = tweak_setup( *add_ref_edge_list_ptr, "Offsetting", 15898 old_body_list2, add_curve_list ); 15899 if (!gme_ptr2) 15900 return CUBIT_FAILURE; 15901 if( gme_ptr != gme_ptr2 ) 15902 { 15903 PRINT_ERROR("Offsetting curves on entities containing surfaces from different\n" 15904 " geometry engines is not allowed.\n"); 15905 return CUBIT_FAILURE; 15906 } 15907 old_body_list.merge_unique( old_body_list2 ); 15908 } 15909 15910 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 15911 { 15912 if( keep_old_body ) 15913 CubitUndo::save_state(); 15914 else 15915 CubitUndo::save_state_with_cubit_file( all_ref_edge_list ); 15916 } 15917 15918 // Do offset 15919 DLIList<BodySM*> new_bodysm_list; 15920 CubitStatus stat; 15921 if( add_curve_list.size() ) 15922 stat = gme_ptr->tweak_offset( curve_list, offset_distance, &add_curve_list, 15923 add_offset_list_ptr, new_bodysm_list, keep_old_body, preview ); 15924 else 15925 stat = gme_ptr->tweak_offset( curve_list, offset_distance, NULL, NULL, 15926 new_bodysm_list, keep_old_body, preview ); 15927 15928 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 15929 if( stat == CUBIT_FAILURE) 15930 CubitUndo::remove_last_undo(); 15931 15932 if( stat == CUBIT_FAILURE ) 15933 return CUBIT_FAILURE; 15934 15935 DLIList<RefEntity*> entities_to_update; 15936 if( preview == CUBIT_FALSE ) 15937 { 15938 // check for resued entities, they have been moved and we need to notify observers 15939 for(int i=0; i<new_bodysm_list.size(); i++) 15940 { 15941 BodySM* bodysm = new_bodysm_list.get_and_step(); 15942 DLIList<TopologyBridge*> to_check; 15943 DLIList<TopologyBridge*> tmp; 15944 DLIList<Surface*> surfs; 15945 bodysm->surfaces(surfs); 15946 DLIList<Curve*> curves; 15947 bodysm->curves(curves); 15948 DLIList<TBPoint*> points; 15949 bodysm->points(points); 15950 to_check.append(bodysm); 15951 to_check.append(bodysm->lump()); 15952 CAST_LIST_TO_PARENT(surfs, tmp); 15953 to_check += tmp; 15954 CAST_LIST_TO_PARENT(curves, tmp); 15955 to_check += tmp; 15956 CAST_LIST_TO_PARENT(points, tmp); 15957 to_check += tmp; 15958 15959 int k; 15960 for(k=0; k<to_check.size(); k++) 15961 if(BridgeManager* m = to_check.get_and_step()->bridge_manager()) 15962 if(TopologyEntity* t = m->topology_entity()) 15963 entities_to_update.append(CAST_TO(t, RefEntity)); 15964 } 15965 15966 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 15967 15968 if( CubitUndo::get_undo_enabled() ) 15969 { 15970 if( stat == CUBIT_FAILURE ) 15971 CubitUndo::remove_last_undo(); 15972 else if( keep_old_body ) 15973 CubitUndo::note_result_bodies( new_body_list ); 15974 } 15975 } 15976 15977 // Update graphics 15978 while (entities_to_update.size()) 15979 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, entities_to_update.pop())); 15980 15981 // Update graphics 15982 DLIList<Body*> moved_bodies(new_body_list); 15983 moved_bodies.intersect(old_body_list); 15984 while (moved_bodies.size()) 15985 moved_bodies.pop()->notify_sub_all_observers( GeometryEvent::GEOMETRY_MODIFIED ); 15986 15987 return stat; 15988 } 15989 15990 15991 CubitStatus GeometryModifyTool::tweak_remove_individually( 15992 DLIList<RefFace*> &ref_face_list, 15993 DLIList<Body*> &new_body_list, 15994 CubitBoolean keep_surface, 15995 CubitBoolean keep_old_body, 15996 CubitBoolean preview ) 15997 { 15998 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 15999 { 16000 if( keep_old_body ) 16001 CubitUndo::save_state(); 16002 else 16003 CubitUndo::save_state_with_cubit_file( ref_face_list ); 16004 } 16005 16006 // Split things up if individual 16007 //build a surfae to volume map 16008 std::map<RefFace*, RefVolume*> surface_to_volume_map; 16009 16010 int i; 16011 for (i = ref_face_list.size(); i--; ) 16012 { 16013 RefFace *tmp_face = ref_face_list.get_and_step(); 16014 RefVolume *tmp_vol = tmp_face->ref_volume(); 16015 surface_to_volume_map.insert( std::map<RefFace*, RefVolume*>::value_type( tmp_face, tmp_vol)); 16016 } 16017 16018 DLIList<RefFace*> one_ref_face; 16019 DLIList<Body*> tmp_new_body_list; 16020 CubitStatus total_rv = CUBIT_FAILURE; 16021 bool extend = true; 16022 16023 // Succeed if any one surface succeeds. 16024 for (i = ref_face_list.size(); i--; ) 16025 { 16026 //make sure that the surface to remove is still in the body... 16027 //that it hasn't been removed from a previous tweak operation 16028 RefFace *tmp_face = ref_face_list.get_and_step(); 16029 std::map<RefFace*, RefVolume*>::iterator tmp_iter; 16030 tmp_iter = surface_to_volume_map.find( tmp_face ); 16031 RefVolume *tmp_vol = tmp_iter->second; 16032 DLIList<RefFace*> ref_face_list; 16033 tmp_vol->ref_faces( ref_face_list ); 16034 if( !ref_face_list.move_to( tmp_face ) ) 16035 continue; 16036 16037 one_ref_face.clean_out(); 16038 one_ref_face.append( tmp_face ); 16039 int id = one_ref_face.get()->id(); 16040 16041 //See if the owning body of the face is a multi-volume body 16042 Body *owning_body = one_ref_face.get()->body(); 16043 int number_volumes_before = owning_body->num_ref_volumes(); 16044 16045 tmp_new_body_list.clean_out(); 16046 16047 CubitStatus rv = this->tweak_remove(one_ref_face, tmp_new_body_list, 16048 extend, keep_surface, keep_old_body, preview ); 16049 if (rv) 16050 { 16051 total_rv = CUBIT_SUCCESS; 16052 if( !preview ) 16053 PRINT_INFO("Successfully removed Surface %d\n\n", id); 16054 else 16055 PRINT_INFO("Successfully removed Surface %d in preview\n\n", id); 16056 16057 //see if we have a multi-volume body or multiple bodies 16058 //if so, we know the original volume was destroyed, so we 16059 //cannot remove any more surfaces because the check above is 16060 //highly likely to crash 16061 bool volume_destroyed = false; 16062 int number_volumes_after = tmp_new_body_list.get()->num_ref_volumes(); 16063 if( number_volumes_after > number_volumes_before ) 16064 volume_destroyed = true; 16065 16066 new_body_list += tmp_new_body_list; 16067 16068 if( volume_destroyed == true ) 16069 { 16070 PRINT_WARNING("Unable to remove more surfaces because multiple bodies\n" 16071 " have been produced from removing surfaces individually\n" ); 16072 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16073 { 16074 if( total_rv == CUBIT_FAILURE ) //didn't remove any surfaces 16075 CubitUndo::remove_last_undo(); 16076 else 16077 CubitUndo::note_result_bodies( new_body_list ); 16078 } 16079 16080 return total_rv; 16081 } 16082 } 16083 else 16084 { 16085 if( !preview ) 16086 PRINT_INFO("Unable to remove Surface %d\n\n", id); 16087 else 16088 PRINT_INFO("Unable to remove Surface %d in preview\n\n", id); 16089 } 16090 } 16091 16092 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16093 { 16094 if( total_rv == CUBIT_FAILURE) 16095 CubitUndo::remove_last_undo(); 16096 else if( keep_old_body || keep_surface ) 16097 CubitUndo::note_result_bodies( new_body_list ); 16098 } 16099 16100 return total_rv; 16101 } 16102 16103 16104 //============================================================================= 16105 // Description: Function to remove surfaces from a body and then extend the 16106 // remaining surfaces to fill the gap or hole. 16107 // Author : Steve Storm 16108 // Date : 03/25/05 16109 //============================================================================= 16110 CubitStatus GeometryModifyTool::tweak_remove_together( 16111 DLIList<RefFace*> &ref_face_list, 16112 DLIList<Body*> &new_body_list, 16113 CubitBoolean extend_adjoining, 16114 CubitBoolean keep_surface, 16115 CubitBoolean keep_old_body, 16116 CubitBoolean preview ) 16117 { 16118 16119 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16120 { 16121 if( keep_old_body ) 16122 CubitUndo::save_state(); 16123 else 16124 CubitUndo::save_state_with_cubit_file( ref_face_list ); 16125 } 16126 16127 CubitStatus stat = tweak_remove( ref_face_list, new_body_list, 16128 extend_adjoining, keep_surface, 16129 keep_old_body, preview ); 16130 16131 if( stat == CUBIT_FAILURE ) 16132 { 16133 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16134 CubitUndo::remove_last_undo(); 16135 16136 return CUBIT_FAILURE; 16137 } 16138 16139 16140 if( preview == CUBIT_FALSE ) 16141 { 16142 if( CubitUndo::get_undo_enabled() ) 16143 { 16144 if( stat == CUBIT_FAILURE ) 16145 CubitUndo::remove_last_undo(); 16146 else if( keep_old_body || keep_surface ) 16147 CubitUndo::note_result_bodies( new_body_list ); 16148 } 16149 } 16150 16151 return CUBIT_SUCCESS; 16152 } 16153 16154 //private funcion...should not be called from outside this class 16155 CubitStatus GeometryModifyTool::tweak_remove( DLIList<RefFace*> &ref_face_list, 16156 DLIList<Body*> &new_body_list, 16157 CubitBoolean extend_adjoining, 16158 CubitBoolean keep_surface, 16159 CubitBoolean keep_old_body, 16160 CubitBoolean preview ) 16161 { 16162 DLIList<Surface*> surface_list(ref_face_list.size()); 16163 DLIList<Body*> old_body_list; 16164 GeometryModifyEngine* gme_ptr; 16165 16166 // clear any preview previews 16167 GfxPreview::clear(); 16168 16169 //collect all neighboring surfaces to those in the list 16170 int i,j; 16171 DLIList<RefFace*> neighboring_surfaces; 16172 DLIList<RefEdge*> merged_ref_edges_before; 16173 for( i=ref_face_list.size(); i--; ) 16174 { 16175 RefFace *tmp_face = ref_face_list.get_and_step(); 16176 DLIList<RefEdge*> ref_edge_list; 16177 tmp_face->ref_edges( ref_edge_list ); 16178 for( j=ref_edge_list.size(); j--; ) 16179 ref_edge_list.get_and_step()->ref_faces( neighboring_surfaces ); 16180 16181 DLIList<RefVertex*> tmp_verts; 16182 tmp_face->ref_vertices( tmp_verts ); 16183 for( j=tmp_verts.size(); j--; ) 16184 { 16185 RefVertex *tmp_vert = tmp_verts.get_and_step(); 16186 DLIList<RefEdge*> tmp_edges; 16187 tmp_vert->ref_edges( tmp_edges ); 16188 int kk; 16189 for( kk=tmp_edges.size(); kk--; ) 16190 { 16191 RefEdge *tmp_edge = tmp_edges.get_and_step(); 16192 if( tmp_edge->is_merged() ) 16193 merged_ref_edges_before.append( tmp_edge); 16194 } 16195 } 16196 } 16197 16198 //uniquify and add other surfaces 16199 neighboring_surfaces.uniquify_unordered(); 16200 neighboring_surfaces += ref_face_list; 16201 16202 gme_ptr = tweak_setup( ref_face_list, "Removing", old_body_list, surface_list, CUBIT_TRUE ); 16203 if (!gme_ptr) 16204 return CUBIT_FAILURE; 16205 16206 DLIList<Surface*> kept_surface_list; 16207 if( keep_surface ) 16208 { 16209 int kk; 16210 for( kk=surface_list.size(); kk--; ) 16211 { 16212 Surface *new_surf = gme_ptr->make_Surface( surface_list.get_and_step() ); 16213 kept_surface_list.append( new_surf ); 16214 } 16215 } 16216 16217 DLIList<BodySM*> body_sms; 16218 for(i=old_body_list.size(); i--;) 16219 { 16220 BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr(); 16221 if(bsm) 16222 body_sms.append_unique(bsm); 16223 } 16224 16225 if(!preview) 16226 { 16227 do_attribute_setup(); 16228 push_attributes_before_modify(body_sms); 16229 } 16230 16231 // Do remove 16232 DLIList<BodySM*> new_bodysm_list; 16233 CubitStatus removal_status = 16234 gme_ptr->tweak_remove( surface_list, 16235 new_bodysm_list, 16236 extend_adjoining, 16237 keep_old_body, 16238 preview ); 16239 16240 16241 if( removal_status == CUBIT_FAILURE ) 16242 { 16243 if(!preview) 16244 remove_pushed_attributes(new_bodysm_list, old_body_list); 16245 if( keep_surface ) 16246 { 16247 int kk; 16248 for( kk=kept_surface_list.size(); kk--; ) 16249 { 16250 Surface *surf = kept_surface_list.get_and_step(); 16251 gme_ptr->get_gqe()->delete_solid_model_entities( surf ); 16252 } 16253 } 16254 if(!preview) 16255 do_attribute_cleanup(); 16256 return CUBIT_FAILURE; 16257 } 16258 else 16259 { 16260 if(!preview) 16261 { 16262 restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr); 16263 remove_pushed_attributes(new_bodysm_list, old_body_list); 16264 } 16265 } 16266 16267 // for each new bodysm, find surfaces that need updating. 16268 // this is to account for some cases where the topology doesn't change, but the geometry does. 16269 DLIList<RefEntity*> entities_to_update; 16270 for(i=0; i<new_bodysm_list.size(); i++) 16271 { 16272 BodySM* bodysm = new_bodysm_list.get_and_step(); 16273 DLIList<Surface*> surfs; 16274 bodysm->surfaces(surfs); 16275 int j; 16276 // find a surface that is also found in our input list 16277 for(j=0; j<surfs.size(); j++, surfs.step()) 16278 { 16279 BridgeManager* man = surfs.get()->bridge_manager(); 16280 if(man) 16281 { 16282 RefFace* ref_face = CAST_TO(man->topology_entity(), RefFace); 16283 if( ref_face && neighboring_surfaces.is_in_list(ref_face) ) 16284 { 16285 // get neighbors 16286 DLIList<TBPoint*> neighbor_points; 16287 surfs.get()->points(neighbor_points); 16288 DLIList<Curve*> neighbor_curves; 16289 DLIList<Surface*> neighbor_surfaces; 16290 DLIList<TopologyBridge*> neighbors; 16291 DLIList<TopologyBridge*> tmp; 16292 int k; 16293 for(k=0; k<neighbor_points.size(); k++) 16294 neighbor_points.get_and_step()->surfaces(neighbor_surfaces); 16295 for(k=0; k<neighbor_points.size(); k++) 16296 neighbor_points.get_and_step()->curves(neighbor_curves); 16297 16298 CAST_LIST_TO_PARENT(neighbor_points, tmp); 16299 neighbors += tmp; 16300 neighbor_curves.uniquify_ordered(); 16301 CAST_LIST_TO_PARENT(neighbor_curves, tmp); 16302 neighbors += tmp; 16303 neighbor_surfaces.uniquify_ordered(); 16304 CAST_LIST_TO_PARENT(neighbor_surfaces, tmp); 16305 neighbors += tmp; 16306 neighbors.append(surfs.get()->lump()); 16307 neighbors.append(surfs.get()->bodysm()); 16308 16309 for(k=0; k<neighbors.size(); k++) 16310 { 16311 if(BridgeManager* m = neighbors.get_and_step()->bridge_manager()) 16312 { 16313 if(TopologyEntity* t = m->topology_entity()) 16314 { 16315 RefEntity *ref_ent = CAST_TO(t, RefEntity ); 16316 entities_to_update.append(ref_ent); 16317 } 16318 } 16319 } 16320 } 16321 } 16322 } 16323 } 16324 16325 16326 DLIList<Body*> kept_surface_bodies; 16327 if( preview == CUBIT_FALSE && keep_surface ) 16328 { 16329 int kk; 16330 for( kk=kept_surface_list.size(); kk--; ) 16331 { 16332 Surface *surf = kept_surface_list.get_and_step(); 16333 Body *new_body = make_Body( surf ); 16334 kept_surface_bodies.append( new_body ); 16335 } 16336 } 16337 16338 // Update DAG 16339 CubitStatus stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 16340 16341 if(!preview) 16342 do_attribute_cleanup(); 16343 16344 if( keep_surface ) 16345 new_body_list += kept_surface_bodies; 16346 16347 if( stat == CUBIT_FAILURE) 16348 return CUBIT_FAILURE; 16349 16350 // Update graphics 16351 while (entities_to_update.size()) 16352 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, entities_to_update.pop())); 16353 16354 16355 //unmerge all curves attached to these vertices after 16356 DLIList<RefEdge*> merged_ref_edges_after; 16357 for( i=new_body_list.size(); i--; ) 16358 { 16359 Body *new_body = new_body_list.get_and_step(); 16360 DLIList<RefVertex*> tmp_verts; 16361 new_body->ref_vertices( tmp_verts); 16362 16363 for( j=tmp_verts.size(); j--; ) 16364 { 16365 RefVertex *tmp_vert = tmp_verts.get_and_step(); 16366 DLIList<RefEdge*> tmp_edges; 16367 if( tmp_vert->is_merged() ) 16368 { 16369 tmp_vert->ref_edges( tmp_edges ); 16370 int k; 16371 for( k=tmp_edges.size(); k--; ) 16372 { 16373 RefEdge *tmp_edge = tmp_edges.get_and_step(); 16374 if( tmp_edge->is_merged() ) 16375 merged_ref_edges_after.append( tmp_edge ); 16376 } 16377 } 16378 } 16379 } 16380 16381 merged_ref_edges_before.uniquify_unordered(); 16382 for( i=merged_ref_edges_before.size(); i--; ) 16383 { 16384 RefEdge *tmp_edge = merged_ref_edges_before.get_and_step(); 16385 if( merged_ref_edges_after.is_in_list( tmp_edge ) ) 16386 MergeTool::instance()->unmerge( tmp_edge ); 16387 } 16388 16389 return CUBIT_SUCCESS; 16390 } 16391 16392 16393 //============================================================================= 16394 // Description: Function to remove curves from a sheet body and then extend the 16395 // remaining curves or fill the gap or hole. 16396 // Author : Steve Storm 16397 // Date : 03/25/05 16398 //============================================================================= 16399 CubitStatus GeometryModifyTool::tweak_remove( DLIList<RefEdge*> &ref_edge_list, 16400 DLIList<Body*> &new_body_list, 16401 CubitBoolean keep_old_body, 16402 CubitBoolean preview ) 16403 { 16404 DLIList<Curve*> curve_list(ref_edge_list.size()); 16405 DLIList<Body*> old_body_list; 16406 GeometryModifyEngine* gme_ptr; 16407 16408 // clear any preview previews 16409 GfxPreview::clear(); 16410 16411 gme_ptr = tweak_setup( ref_edge_list, "Removing", old_body_list, curve_list ); 16412 if( !gme_ptr ) 16413 return CUBIT_FAILURE; 16414 16415 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16416 { 16417 if( keep_old_body ) 16418 CubitUndo::save_state(); 16419 else 16420 CubitUndo::save_state_with_cubit_file( ref_edge_list ); 16421 } 16422 16423 // Do remove 16424 DLIList<BodySM*> new_bodysm_list; 16425 CubitStatus stat = gme_ptr->tweak_remove( curve_list, new_bodysm_list, 16426 keep_old_body, preview ); 16427 //collect all neighboring curves to those in the list 16428 int i, j; 16429 DLIList<RefEdge*> neighboring_curves; 16430 for( i=ref_edge_list.size(); i--; ) 16431 { 16432 RefEdge *tmp_edge = ref_edge_list.get_and_step(); 16433 DLIList<RefVertex*> tmp_ref_vertex_list; 16434 tmp_edge->ref_vertices( tmp_ref_vertex_list ); 16435 for( j=tmp_ref_vertex_list.size(); j--; ) 16436 tmp_ref_vertex_list.get_and_step()->ref_edges( neighboring_curves ); 16437 } 16438 16439 //uniquify and add other curves 16440 neighboring_curves.uniquify_unordered(); 16441 //neighboring_curves += ref_edge_list; 16442 16443 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16444 if( stat == CUBIT_FAILURE ) 16445 CubitUndo::remove_last_undo(); 16446 16447 if( stat == CUBIT_FAILURE) 16448 return stat; 16449 16450 // loop body sm list and find curves that need updating. 16451 // this is to account for some cases where the topology doesn't change, but the geometry does. 16452 DLIList<RefEntity*> entities_to_update; 16453 for(i=0; i<new_bodysm_list.size(); i++) 16454 { 16455 BodySM* bodysm = new_bodysm_list.get_and_step(); 16456 DLIList<Curve*> curves; 16457 bodysm->curves(curves); 16458 int j; 16459 // find a surface that is also found in our input list 16460 for(j=0; j<curves.size(); j++, curves.step()) 16461 { 16462 BridgeManager* man = curves.get()->bridge_manager(); 16463 if(man) 16464 { 16465 RefEdge* ref_edge = CAST_TO(man->topology_entity(), RefEdge); 16466 if( ref_edge && neighboring_curves.is_in_list(ref_edge) ) 16467 { 16468 // get neighbors 16469 DLIList<TBPoint*> neighbor_points; 16470 curves.get()->points(neighbor_points); 16471 DLIList<Curve*> neighbor_curves; 16472 DLIList<Surface*> neighbor_surfaces; 16473 DLIList<TopologyBridge*> neighbors; 16474 DLIList<TopologyBridge*> tmp; 16475 int k; 16476 for(k=0; k<neighbor_points.size(); k++) 16477 neighbor_points.get_and_step()->surfaces(neighbor_surfaces); 16478 for(k=0; k<neighbor_points.size(); k++) 16479 neighbor_points.get_and_step()->curves(neighbor_curves); 16480 16481 CAST_LIST_TO_PARENT(neighbor_points, tmp); 16482 neighbors += tmp; 16483 neighbor_curves.uniquify_ordered(); 16484 CAST_LIST_TO_PARENT(neighbor_curves, tmp); 16485 neighbors += tmp; 16486 neighbor_surfaces.uniquify_ordered(); 16487 CAST_LIST_TO_PARENT(neighbor_surfaces, tmp); 16488 neighbors += tmp; 16489 //neighbors.append(curves.get()->lump()); 16490 //neighbors.append(curves.get()->bodysm()); 16491 16492 for(k=0; k<neighbors.size(); k++) 16493 { 16494 if(BridgeManager* m = neighbors.get_and_step()->bridge_manager()) 16495 { 16496 if(TopologyEntity* t = m->topology_entity()) 16497 { 16498 RefEntity *ref_ent = CAST_TO(t, RefEntity ); 16499 entities_to_update.append(ref_ent); 16500 } 16501 } 16502 } 16503 } 16504 } 16505 } 16506 } 16507 16508 if(preview == CUBIT_FALSE ) 16509 { 16510 // Update DAG 16511 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 16512 16513 // Update graphics 16514 while (entities_to_update.size()) 16515 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, entities_to_update.pop())); 16516 16517 if( CubitUndo::get_undo_enabled() ) 16518 { 16519 if( stat == CUBIT_FAILURE ) 16520 CubitUndo::remove_last_undo(); 16521 else if( keep_old_body ) 16522 CubitUndo::note_result_bodies( new_body_list ); 16523 } 16524 } 16525 16526 return stat; 16527 } 16528 16529 16530 //============================================================================= 16531 // Description: Tweak specified faces of a volume or volumes up to a target 16532 // surface or set of connected target surfaces. 16533 // Author : Steve Storm 16534 // Date : 03/25/05 16535 //============================================================================= 16536 CubitStatus GeometryModifyTool::tweak_target( DLIList<RefFace*> &ref_face_list, 16537 DLIList<RefFace*> &target_face_list, 16538 DLIList<Body*> &new_body_list, 16539 CubitBoolean extend_flg, 16540 CubitPlane *limit_plane, 16541 CubitBoolean reverse_flg, 16542 CubitBoolean keep_old_body, 16543 CubitBoolean preview ) 16544 { 16545 DLIList<Surface*> surface_list(ref_face_list.size()); 16546 DLIList<Surface*> target_surf_list(target_face_list.size()); 16547 DLIList<Body*> old_body_list; 16548 GeometryModifyEngine *gme_ptr1, *gme_ptr2; 16549 16550 gme_ptr1 = tweak_setup( ref_face_list, "Tweaking", old_body_list, surface_list, CUBIT_TRUE ); 16551 if (!gme_ptr1) 16552 return CUBIT_FAILURE; 16553 16554 DLIList<Body*> old_body_list2; 16555 gme_ptr2 = tweak_setup( target_face_list, "Tweaking", old_body_list2, target_surf_list, CUBIT_TRUE ); 16556 if (!gme_ptr2) 16557 return CUBIT_FAILURE; 16558 16559 if( gme_ptr1 != gme_ptr2 ) 16560 { 16561 PRINT_ERROR( "Target surfaces must belong to same geometry engine as tweaked surfaces.\n" ); 16562 return CUBIT_FAILURE; 16563 } 16564 16565 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16566 { 16567 if( keep_old_body ) 16568 CubitUndo::save_state(); 16569 else 16570 CubitUndo::save_state_with_cubit_file( ref_face_list ); 16571 } 16572 16573 int i; 16574 DLIList<Body*> all_bodies = old_body_list; 16575 all_bodies += old_body_list2; 16576 DLIList<BodySM*> body_sms; 16577 for(i=all_bodies.size(); i--;) 16578 { 16579 BodySM* bsm = all_bodies.get_and_step()->get_body_sm_ptr(); 16580 if(bsm) 16581 body_sms.append_unique(bsm); 16582 } 16583 16584 if(!preview) 16585 { 16586 do_attribute_setup(); 16587 push_attributes_before_modify(body_sms); 16588 } 16589 16590 // Do tweak to target 16591 DLIList<BodySM*> new_bodysm_list; 16592 CubitStatus stat = gme_ptr1->tweak_target( surface_list, target_surf_list, 16593 new_bodysm_list, extend_flg, 16594 limit_plane, reverse_flg, 16595 keep_old_body, preview ); 16596 16597 16598 if( stat == CUBIT_FAILURE ) 16599 { 16600 if(!preview) 16601 remove_pushed_attributes(new_bodysm_list, all_bodies); 16602 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16603 CubitUndo::remove_last_undo(); 16604 if(!preview) 16605 do_attribute_cleanup(); 16606 return CUBIT_FAILURE; 16607 } 16608 else 16609 { 16610 if(!preview) 16611 { 16612 restore_vg_after_modify(new_bodysm_list, all_bodies, gme_ptr1); 16613 remove_pushed_attributes(new_bodysm_list, all_bodies); 16614 } 16615 } 16616 16617 // Collect all the old_faces to be compared against new_faces later...DJQ 16618 DLIList<RefFace*> old_faces; 16619 for (i = 0; i < old_body_list.size(); i++) 16620 { 16621 Body *old_body = old_body_list.get_and_step(); 16622 DLIList<RefFace*> tmp_faces; 16623 old_body->ref_faces(tmp_faces); 16624 old_faces +=tmp_faces; 16625 } 16626 16627 // Update DAG 16628 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 16629 16630 if(!preview) 16631 do_attribute_cleanup(); 16632 16633 if( stat == CUBIT_FAILURE ) 16634 { 16635 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16636 CubitUndo::remove_last_undo(); 16637 return CUBIT_FAILURE; 16638 } 16639 16640 //collect all the new faces 16641 DLIList<RefFace*> new_faces; 16642 for( i=new_body_list.size(); i--; ) 16643 { 16644 Body *new_body = new_body_list.get_and_step(); 16645 DLIList<RefFace*> tmp_faces; 16646 new_body->ref_faces( tmp_faces ); 16647 new_faces += tmp_faces; 16648 } 16649 16650 // Compare the new_faces list with the old_faces list to determine which faces are created 16651 // Add these faces to the all_ref_face_list to check for its neighbors...DJQ 16652 DLIList<RefFace*> difference = new_faces; 16653 difference -= old_faces; 16654 ref_face_list += difference; 16655 16656 16657 // loop body sm list and find surfaces that need updating. 16658 // this is to account for some cases where the topology doesn't change, but the geometry does. 16659 DLIList<RefEntity*> entities_to_update; 16660 for(i=0; i<new_bodysm_list.size(); i++) 16661 { 16662 BodySM* bodysm = new_bodysm_list.get_and_step(); 16663 DLIList<Surface*> surfs; 16664 bodysm->surfaces(surfs); 16665 int j; 16666 // find a surface that is also found in our input list 16667 // some times the target surface gets modified 16668 for(j=0; j<surfs.size(); j++, surfs.step()) 16669 { 16670 BridgeManager* man = surfs.get()->bridge_manager(); 16671 if(man) 16672 { 16673 RefFace* ref_face = CAST_TO(man->topology_entity(), RefFace); 16674 if(ref_face && (ref_face_list.is_in_list(ref_face) || 16675 target_face_list.is_in_list(ref_face))) 16676 { 16677 // get neighbors 16678 DLIList<TBPoint*> neighbor_points; 16679 surfs.get()->points(neighbor_points); 16680 DLIList<Curve*> neighbor_curves; 16681 DLIList<Surface*> neighbor_surfaces; 16682 DLIList<TopologyBridge*> neighbors; 16683 DLIList<TopologyBridge*> tmp; 16684 int k; 16685 for(k=0; k<neighbor_points.size(); k++) 16686 neighbor_points.get_and_step()->surfaces(neighbor_surfaces); 16687 for(k=0; k<neighbor_points.size(); k++) 16688 neighbor_points.get_and_step()->curves(neighbor_curves); 16689 16690 CAST_LIST_TO_PARENT(neighbor_points, tmp); 16691 neighbors += tmp; 16692 neighbor_curves.uniquify_ordered(); 16693 CAST_LIST_TO_PARENT(neighbor_curves, tmp); 16694 neighbors += tmp; 16695 neighbor_surfaces.uniquify_ordered(); 16696 CAST_LIST_TO_PARENT(neighbor_surfaces, tmp); 16697 neighbors += tmp; 16698 neighbors.append(surfs.get()->lump()); 16699 neighbors.append(surfs.get()->bodysm()); 16700 16701 for(k=0; k<neighbors.size(); k++) 16702 if(BridgeManager* m = neighbors.get_and_step()->bridge_manager()) 16703 if(TopologyEntity* t = m->topology_entity()) 16704 entities_to_update.append(CAST_TO(t, RefEntity)); 16705 } 16706 } 16707 } 16708 } 16709 16710 //unmerge any merged adjacent surfaces or 16711 //merged curves in unmerged adjacent surfaces 16712 DLIList<RefFace*> adjacent_faces_to_unmerge; 16713 DLIList<RefEdge*> adjacent_edges_to_unmerge; 16714 for(i=ref_face_list.size(); i--;) 16715 { 16716 RefFace *tweaked_face = ref_face_list.get_and_step(); 16717 if( !new_faces.move_to( tweaked_face ) ) 16718 continue; 16719 16720 //get all the edges of the face you tweaked 16721 DLIList<RefEdge*> tweaked_face_edges; 16722 tweaked_face->ref_edges( tweaked_face_edges ); 16723 adjacent_edges_to_unmerge += tweaked_face_edges; 16724 16725 //get all the adjacent faces to this edge 16726 int j; 16727 for( j=tweaked_face_edges.size(); j--; ) 16728 { 16729 RefEdge *tmp_edge = tweaked_face_edges.get_and_step(); 16730 DLIList<RefFace*> tmp_faces; 16731 tmp_edge->ref_faces( tmp_faces ); 16732 tmp_faces.remove( tweaked_face ); 16733 adjacent_faces_to_unmerge += tmp_faces; 16734 } 16735 16736 //get all edges not in the surface, 16737 //sharing vertices with the surface 16738 DLIList<RefVertex*> ref_vertices; 16739 tweaked_face->ref_vertices( ref_vertices ); 16740 for( j=ref_vertices.size(); j--; ) 16741 { 16742 RefVertex *tmp_vert = ref_vertices.get_and_step(); 16743 DLIList<RefEdge*> ref_edges; 16744 tmp_vert->ref_edges( ref_edges ); 16745 16746 int k; 16747 for( k=ref_edges.size(); k--; ) 16748 { 16749 RefEdge *tmp_edge = ref_edges.get_and_step(); 16750 if( !tweaked_face_edges.move_to( tmp_edge ) ) 16751 adjacent_edges_to_unmerge.append( tmp_edge ); 16752 } 16753 } 16754 } 16755 16756 //unmerge any adjacent faces 16757 adjacent_faces_to_unmerge.uniquify_unordered(); 16758 for( i=adjacent_faces_to_unmerge.size(); i--; ) 16759 { 16760 RefFace *ref_face = adjacent_faces_to_unmerge.get_and_step(); 16761 16762 DLIList<TopologyBridge*> bridge_list; 16763 ref_face->bridge_manager()->get_bridge_list(bridge_list); 16764 if (bridge_list.size() > 1) 16765 { 16766 if( MergeTool::instance()->unmerge( ref_face ) ) 16767 PRINT_WARNING("Unmerging Surface %d\n", ref_face->id() ); 16768 } 16769 } 16770 16771 //unmerge any adjacent edges 16772 adjacent_edges_to_unmerge.uniquify_unordered(); 16773 for( i=adjacent_edges_to_unmerge.size(); i--; ) 16774 { 16775 RefEdge *ref_edge = adjacent_edges_to_unmerge.get_and_step(); 16776 DLIList<TopologyBridge*> bridge_list; 16777 ref_edge->bridge_manager()->get_bridge_list(bridge_list); 16778 if (bridge_list.size() > 1) 16779 { 16780 if( MergeTool::instance()->unmerge( ref_edge) ) 16781 PRINT_WARNING("Unmerging Curve %d\n", ref_edge->id() ); 16782 } 16783 } 16784 16785 if( CubitUndo::get_undo_enabled() && keep_old_body ) 16786 CubitUndo::note_result_bodies( new_body_list ); 16787 16788 // Update graphics 16789 while (entities_to_update.size()) 16790 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, entities_to_update.pop())); 16791 16792 16793 return CUBIT_SUCCESS; 16794 } 16795 16796 //============================================================================= 16797 // Description: Tweak specified faces of a volume or volumes up to a target 16798 // plane. 16799 // Author : Steve Storm 16800 // Date : 05/10/05 16801 //============================================================================= 16802 CubitStatus GeometryModifyTool::tweak_target( DLIList<RefFace*> &ref_face_list, 16803 CubitPlane &plane, 16804 DLIList<Body*> &new_body_list, 16805 CubitBoolean reverse_flg, 16806 CubitBoolean keep_old_body, 16807 CubitBoolean preview ) 16808 { 16809 DLIList<Surface*> surface_list(ref_face_list.size()+1); 16810 DLIList<Body*> old_body_list; 16811 GeometryModifyEngine* gme_ptr; 16812 16813 gme_ptr = tweak_setup( ref_face_list, "Tweaking", old_body_list, surface_list, CUBIT_TRUE ); 16814 if (!gme_ptr) 16815 return CUBIT_FAILURE; 16816 16817 // Create a target Surface from the plane (arbitrarily 10.0 X 10.0 in size) 16818 16819 // Get corners of the surface 16820 CubitVector normal = plane.normal(); 16821 CubitVector x, y; 16822 normal.orthogonal_vectors( x, y ); 16823 CubitVector p1 = plane.point_on_plane(); 16824 CubitVector p2, p3, p4; 16825 p1.next_point( x, 5.0, p1 ); 16826 p1.next_point( y, 5.0, p1 ); 16827 p1.next_point( -x, 10.0, p2 ); 16828 p2.next_point( -y, 10.0, p3 ); 16829 p3.next_point( x, 10.0, p4 ); 16830 16831 BodySM* bodysm_ptr = gme_ptr->planar_sheet( p1, p2, p3, p4 ); 16832 if( !bodysm_ptr ) 16833 { 16834 PRINT_ERROR( "unable to create target surface from plane\n" ); 16835 return CUBIT_FAILURE; 16836 } 16837 16838 DLIList<Surface*> target_surf_list; 16839 bodysm_ptr->surfaces( target_surf_list ); 16840 if( !target_surf_list.size() ) 16841 { 16842 PRINT_ERROR( "unable to create target surface from plane\n" ); 16843 return CUBIT_FAILURE; 16844 } 16845 16846 int i; 16847 DLIList<BodySM*> body_sms; 16848 for(i=old_body_list.size(); i--;) 16849 { 16850 BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr(); 16851 if(bsm) 16852 body_sms.append_unique(bsm); 16853 } 16854 16855 if(!preview) 16856 { 16857 do_attribute_setup(); 16858 push_attributes_before_modify(body_sms); 16859 } 16860 16861 // Do tweak to target 16862 DLIList<BodySM*> new_bodysm_list; 16863 CubitStatus stat = gme_ptr->tweak_target( surface_list, target_surf_list, 16864 new_bodysm_list, CUBIT_TRUE, 16865 NULL, reverse_flg, keep_old_body, 16866 preview ); 16867 16868 16869 if( stat == CUBIT_FAILURE ) 16870 { 16871 if(!preview) 16872 remove_pushed_attributes(new_bodysm_list, old_body_list); 16873 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16874 CubitUndo::remove_last_undo(); 16875 if(!preview) 16876 do_attribute_cleanup(); 16877 return CUBIT_FAILURE; 16878 } 16879 else 16880 { 16881 if(!preview) 16882 { 16883 restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr); 16884 remove_pushed_attributes(new_bodysm_list, old_body_list); 16885 } 16886 } 16887 16888 // Delete temporary sheet body 16889 bodysm_ptr->get_geometry_query_engine()->delete_solid_model_entities( bodysm_ptr ); 16890 16891 // Update DAG 16892 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 16893 16894 if(!preview) 16895 do_attribute_cleanup(); 16896 16897 if( stat == CUBIT_FAILURE ) 16898 { 16899 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16900 CubitUndo::remove_last_undo(); 16901 return CUBIT_FAILURE; 16902 } 16903 16904 // Update graphics 16905 DLIList<Body*> moved_bodies(new_body_list); 16906 moved_bodies.intersect(old_body_list); 16907 while (moved_bodies.size()) 16908 moved_bodies.pop()->notify_sub_all_observers( GeometryEvent::GEOMETRY_MODIFIED ); 16909 16910 return CUBIT_SUCCESS; 16911 } 16912 16913 //============================================================================= 16914 // Description: Tweak specified edges of a surface or set of surfaces (in sheet 16915 // bodies) up to a target surface or set of target surfaces. 16916 // Author : Steve Storm 16917 // Date : 03/25/05 16918 //============================================================================= 16919 CubitStatus GeometryModifyTool::tweak_target( DLIList<RefEdge*> &ref_edge_list, 16920 DLIList<RefFace*> &target_face_list, 16921 DLIList<Body*> &new_body_list, 16922 CubitBoolean extend_flg, 16923 CubitPlane *limit_plane, 16924 CubitBoolean reverse_flg, 16925 CubitBoolean keep_old, 16926 CubitBoolean preview, 16927 double max_area_increase /*= 0%*/ ) 16928 { 16929 DLIList<Curve*> curve_list(ref_edge_list.size()); 16930 DLIList<Surface*> target_surf_list(target_face_list.size()); 16931 DLIList<Body*> old_body_list; 16932 GeometryModifyEngine *gme_ptr1, *gme_ptr2; 16933 16934 gme_ptr1 = tweak_setup( ref_edge_list, "Tweaking", old_body_list, curve_list ); 16935 if( !gme_ptr1 ) 16936 return CUBIT_FAILURE; 16937 16938 DLIList<Body*> old_body_list2; 16939 gme_ptr2 = tweak_setup( target_face_list, "Tweaking", old_body_list2, target_surf_list ); 16940 if( !gme_ptr2 ) 16941 return CUBIT_FAILURE; 16942 16943 if( gme_ptr1 != gme_ptr2 ) 16944 { 16945 PRINT_ERROR( "Target surface(s) must belong to same geometry engine as tweaked curves.\n" ); 16946 return CUBIT_FAILURE; 16947 } 16948 16949 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16950 { 16951 if( keep_old ) 16952 CubitUndo::save_state(); 16953 else 16954 CubitUndo::save_state_with_cubit_file( ref_edge_list ); 16955 } 16956 16957 // Do tweak to target 16958 DLIList<BodySM*> new_bodysm_list; 16959 CubitStatus stat = gme_ptr1->tweak_target( curve_list, target_surf_list, 16960 new_bodysm_list, extend_flg, 16961 limit_plane, reverse_flg, 16962 keep_old, preview, max_area_increase ); 16963 16964 if( stat == CUBIT_FAILURE ) 16965 { 16966 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16967 CubitUndo::remove_last_undo(); 16968 return CUBIT_FAILURE; 16969 } 16970 16971 // Update DAG 16972 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 16973 16974 16975 if( stat == CUBIT_FAILURE ) 16976 { 16977 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16978 CubitUndo::remove_last_undo(); 16979 return CUBIT_FAILURE; 16980 } 16981 16982 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 16983 { 16984 if( keep_old ) 16985 CubitUndo::note_result_bodies( new_body_list ); 16986 } 16987 16988 // Update graphics 16989 DLIList<Body*> moved_bodies(new_body_list); 16990 moved_bodies.intersect(old_body_list); 16991 while (moved_bodies.size()) 16992 moved_bodies.pop()->notify_sub_all_observers( GeometryEvent::GEOMETRY_MODIFIED ); 16993 16994 return CUBIT_SUCCESS; 16995 } 16996 16997 //============================================================================= 16998 // Description: Tweak specified edges of a surface or set of surfaces (in sheet 16999 // bodies) up to a target plane. 17000 // Author : Steve Storm 17001 // Date : 03/25/05 17002 //============================================================================= 17003 CubitStatus GeometryModifyTool::tweak_target( DLIList<RefEdge*> &ref_edge_list, 17004 CubitPlane &plane, 17005 DLIList<Body*> &new_body_list, 17006 CubitBoolean reverse_flg, 17007 CubitBoolean keep_old, 17008 CubitBoolean preview ) 17009 { 17010 DLIList<Curve*> curve_list(ref_edge_list.size()); 17011 DLIList<Body*> old_body_list; 17012 GeometryModifyEngine* gme_ptr; 17013 17014 gme_ptr = tweak_setup( ref_edge_list, "Tweaking", old_body_list, curve_list ); 17015 if( !gme_ptr ) 17016 return CUBIT_FAILURE; 17017 17018 // Create a target Surface from the plane (arbitrarily 10.0 X 10.0 in size) 17019 17020 // Get corners of the surface 17021 CubitVector normal = plane.normal(); 17022 CubitVector x, y; 17023 normal.orthogonal_vectors( x, y ); 17024 CubitVector p1 = plane.point_on_plane(); 17025 CubitVector p2, p3, p4; 17026 p1.next_point( x, 5.0, p1 ); 17027 p1.next_point( y, 5.0, p1 ); 17028 p1.next_point( -x, 10.0, p2 ); 17029 p2.next_point( -y, 10.0, p3 ); 17030 p3.next_point( x, 10.0, p4 ); 17031 17032 BodySM* bodysm_ptr = gme_ptr->planar_sheet( p1, p2, p3, p4 ); 17033 if( !bodysm_ptr ) 17034 { 17035 PRINT_ERROR( "unable to create target surface from plane\n" ); 17036 return CUBIT_FAILURE; 17037 } 17038 17039 DLIList<Surface*> target_surf_list; 17040 bodysm_ptr->surfaces( target_surf_list ); 17041 if( !target_surf_list.size() ) 17042 { 17043 PRINT_ERROR( "unable to create target surface from plane\n" ); 17044 return CUBIT_FAILURE; 17045 } 17046 17047 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 17048 { 17049 if( keep_old ) 17050 CubitUndo::save_state(); 17051 else 17052 CubitUndo::save_state_with_cubit_file( ref_edge_list ); 17053 } 17054 17055 // Do tweak to target 17056 DLIList<BodySM*> new_bodysm_list; 17057 CubitStatus stat = gme_ptr->tweak_target( curve_list, target_surf_list, 17058 new_bodysm_list, CUBIT_TRUE, 17059 NULL, reverse_flg, keep_old, 17060 preview ); 17061 17062 if( stat == CUBIT_FAILURE ) 17063 { 17064 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 17065 CubitUndo::remove_last_undo(); 17066 return CUBIT_FAILURE; 17067 } 17068 17069 // Delete temporary sheet body 17070 bodysm_ptr->get_geometry_query_engine()->delete_solid_model_entities( bodysm_ptr ); 17071 17072 // Update DAG 17073 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 17074 17075 if( stat == CUBIT_FAILURE ) 17076 { 17077 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 17078 CubitUndo::remove_last_undo(); 17079 return CUBIT_FAILURE; 17080 } 17081 17082 if( CubitUndo::get_undo_enabled() && keep_old ) 17083 CubitUndo::note_result_bodies( new_body_list ); 17084 17085 // Update graphics 17086 DLIList<Body*> moved_bodies(new_body_list); 17087 moved_bodies.intersect(old_body_list); 17088 while (moved_bodies.size()) 17089 moved_bodies.pop()->notify_sub_all_observers( GeometryEvent::GEOMETRY_MODIFIED ); 17090 17091 return CUBIT_SUCCESS; 17092 } 17093 17094 //============================================================================= 17095 // Description: Tweak specified edges of a sheet body or bodies up to target 17096 // curves that are part of a sheet body. The target is a surface 17097 // created by thickening the owning surface of the target curves. 17098 // Author : Steve Storm 17099 // Date : 03/25/05 17100 //============================================================================= 17101 CubitStatus GeometryModifyTool::tweak_target( DLIList<RefEdge*> &ref_edge_list, 17102 DLIList<RefEdge*> &target_edge_list, 17103 DLIList<Body*> &new_body_list, 17104 CubitBoolean extend_flg, 17105 CubitPlane *limit_plane, 17106 CubitBoolean reverse_flg, 17107 CubitBoolean keep_old, 17108 CubitBoolean preview, 17109 double max_area_increase /*= 0*/ ) 17110 { 17111 DLIList<Curve*> curve_list(ref_edge_list.size()); 17112 DLIList<Curve*> target_curve_list(target_edge_list.size()); 17113 DLIList<Body*> old_body_list; 17114 GeometryModifyEngine *gme_ptr1, *gme_ptr2; 17115 17116 gme_ptr1 = tweak_setup( ref_edge_list, "Tweaking", old_body_list, curve_list ); 17117 if( !gme_ptr1 ) 17118 return CUBIT_FAILURE; 17119 17120 DLIList<Body*> old_body_list2; 17121 gme_ptr2 = tweak_setup( target_edge_list, "Tweaking", old_body_list2, target_curve_list ); 17122 if( !gme_ptr2 ) 17123 return CUBIT_FAILURE; 17124 17125 if( gme_ptr1 != gme_ptr2 ) 17126 { 17127 PRINT_ERROR( "Target curves must belong to same geometry engine as tweaked curves.\n" ); 17128 return CUBIT_FAILURE; 17129 } 17130 17131 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 17132 { 17133 if( keep_old ) 17134 CubitUndo::save_state(); 17135 else 17136 CubitUndo::save_state_with_cubit_file( ref_edge_list ); 17137 } 17138 17139 // Do tweak to target 17140 DLIList<BodySM*> new_bodysm_list; 17141 CubitStatus stat = gme_ptr1->tweak_target( curve_list, target_curve_list, 17142 new_bodysm_list, extend_flg, 17143 limit_plane, reverse_flg, 17144 keep_old, preview, max_area_increase ); 17145 17146 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 17147 if( stat == CUBIT_FAILURE ) 17148 CubitUndo::remove_last_undo(); 17149 17150 if( stat == CUBIT_FAILURE) 17151 return stat; 17152 17153 DLIList<RefEntity*> entities_to_update; 17154 if( preview == CUBIT_FALSE ) 17155 { 17156 // check for resued entities, they have been moved and we need to notify observers 17157 int i; 17158 for(i=0; i<new_bodysm_list.size(); i++) 17159 { 17160 BodySM* bodysm = new_bodysm_list.get_and_step(); 17161 DLIList<TopologyBridge*> to_check; 17162 DLIList<TopologyBridge*> tmp; 17163 DLIList<Surface*> surfs; 17164 bodysm->surfaces(surfs); 17165 DLIList<Curve*> curves; 17166 bodysm->curves(curves); 17167 DLIList<TBPoint*> points; 17168 bodysm->points(points); 17169 to_check.append(bodysm); 17170 to_check.append(bodysm->lump()); 17171 CAST_LIST_TO_PARENT(surfs, tmp); 17172 to_check += tmp; 17173 CAST_LIST_TO_PARENT(curves, tmp); 17174 to_check += tmp; 17175 CAST_LIST_TO_PARENT(points, tmp); 17176 to_check += tmp; 17177 17178 int k; 17179 for(k=0; k<to_check.size(); k++) 17180 if(BridgeManager* m = to_check.get_and_step()->bridge_manager()) 17181 if(TopologyEntity* t = m->topology_entity()) 17182 entities_to_update.append(CAST_TO(t, RefEntity)); 17183 } 17184 17185 // Update DAG 17186 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 17187 17188 if( CubitUndo::get_undo_enabled() ) 17189 { 17190 if( stat == CUBIT_FAILURE ) 17191 CubitUndo::remove_last_undo(); 17192 else if( keep_old ) 17193 CubitUndo::note_result_bodies( new_body_list ); 17194 } 17195 } 17196 17197 // Update graphics 17198 while (entities_to_update.size()) 17199 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, entities_to_update.pop())); 17200 17201 // Update graphics 17202 DLIList<Body*> moved_bodies(new_body_list); 17203 moved_bodies.intersect(old_body_list); 17204 while (moved_bodies.size()) 17205 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GEOMETRY_MODIFIED, moved_bodies.pop())); 17206 17207 return stat; 17208 } 17209 17210 //============================================================================= 17211 // Description: Tweak specified vertex of a sheet body to a given location. 17212 // The given vertex must be part of a planar surface or surfaces 17213 // attached to linear curves only. The given location will be 17214 // projected to be on the planar surface(s) before being used. 17215 // Author : Steve Storm 17216 // Date : 09/09/08 17217 //============================================================================= 17218 CubitStatus 17219 GeometryModifyTool::tweak_target( RefVertex *ref_vertex_ptr, 17220 DLIList<RefFace*> &modify_ref_face_list, 17221 CubitVector &target_loc, 17222 Body *&new_Body_ptr, 17223 CubitBoolean keep_old, 17224 CubitBoolean preview ) 17225 { 17226 if( modify_ref_face_list.size() == 0 ) 17227 { 17228 PRINT_ERROR( "No surfaces found to modify\n" ); 17229 return CUBIT_FAILURE; 17230 } 17231 17232 int i; 17233 RefFace *ref_face_ptr; 17234 17235 // Check to make sure vertex is part of all given surfaces 17236 modify_ref_face_list.reset(); 17237 for( i=modify_ref_face_list.size(); i--; ) 17238 { 17239 ref_face_ptr = modify_ref_face_list.get_and_step(); 17240 17241 if( !ref_face_ptr->is_directly_related( ref_vertex_ptr ) ) 17242 { 17243 PRINT_ERROR( "Vertex %d is not part of 'modify' Surface %d\n", 17244 ref_vertex_ptr->id(), ref_face_ptr->id() ); 17245 return CUBIT_FAILURE; 17246 } 17247 } 17248 17249 GeometryModifyEngine *gme_ptr; 17250 DLIList<RefVertex*> ref_vertex_list(1); 17251 ref_vertex_list.append( ref_vertex_ptr ); 17252 DLIList<Body*> old_body_list; 17253 DLIList<TBPoint*> point_list(1); 17254 gme_ptr = tweak_setup( ref_vertex_list, "Tweaking", old_body_list, point_list ); 17255 if( !gme_ptr ) 17256 return CUBIT_FAILURE; 17257 17258 // We already made sure the vertex is part of all of the modify faces, so 17259 // just use the common_modify_engine function to get the surface_list 17260 DLIList<Surface*> surface_list; 17261 if( !common_modify_engine( modify_ref_face_list, surface_list ) ) 17262 return CUBIT_FAILURE; 17263 17264 // Make sure part of a sheet body, not a solid body 17265 Body *body_ptr = ref_vertex_ptr->body(); 17266 if( !body_ptr->is_sheet_body() ) 17267 { 17268 PRINT_ERROR( "Vertex %d is not in a sheet body - Body %d is solid.\n" 17269 " Tweaking a vertex to a target currently not possible on solid bodies.\n", 17270 ref_vertex_ptr->id(), body_ptr->id() ); 17271 return CUBIT_FAILURE; 17272 } 17273 17274 // Make sure all the given surfaces are planar 17275 modify_ref_face_list.reset(); 17276 for( i=modify_ref_face_list.size(); i--; ) 17277 { 17278 ref_face_ptr = modify_ref_face_list.get_and_step(); 17279 17280 if( !ref_face_ptr->is_planar() ) 17281 { 17282 PRINT_ERROR( "Surfaces to modify must be planar - Surface %d is not planar\n", ref_face_ptr->id() ); 17283 return CUBIT_FAILURE; 17284 } 17285 } 17286 17287 // Make sure all curves (on modify surfaces) attached to the given vertex are linear 17288 // Get all attached curves 17289 int j; 17290 DLIList<RefEdge*> ref_edge_list; 17291 ref_vertex_ptr->ref_edges( ref_edge_list ); 17292 RefEdge *ref_edge_ptr; 17293 for( i=ref_edge_list.size(); i--; ) 17294 { 17295 ref_edge_ptr = ref_edge_list.get_and_step(); 17296 17297 // Check to see if this edge is linear, if it is in one of the modify surfaces 17298 modify_ref_face_list.reset(); 17299 for( j=modify_ref_face_list.size(); j--; ) 17300 { 17301 ref_face_ptr = modify_ref_face_list.get_and_step(); 17302 if( ref_face_ptr->is_directly_related( ref_edge_ptr ) ) 17303 { 17304 Curve *curve_ptr = ref_edge_ptr->get_curve_ptr(); 17305 GeometryType curve_type = curve_ptr->geometry_type(); 17306 if( curve_type != STRAIGHT_CURVE_TYPE ) 17307 { 17308 PRINT_ERROR( "Curve %d is not linear. Curves that are in the 'modify'\n" 17309 " surfaces attached to the tweak vertex must be linear.\n", 17310 ref_edge_ptr->id() ); 17311 return CUBIT_FAILURE; 17312 } 17313 else 17314 break; 17315 } 17316 } 17317 } 17318 17319 // Project the location to the given surfaces and make sure all of these locations 17320 // are the same 17321 modify_ref_face_list.reset(); 17322 17323 CubitVector ref_loc( target_loc ); // Reference location 17324 ref_face_ptr = modify_ref_face_list.get_and_step(); 17325 ref_face_ptr->move_to_surface( ref_loc ); 17326 int ref_surf_id = ref_face_ptr->id(); 17327 17328 for( i=modify_ref_face_list.size()-1; i--; ) 17329 { 17330 ref_face_ptr = modify_ref_face_list.get_and_step(); 17331 17332 CubitVector proj_loc( target_loc ); 17333 ref_face_ptr->move_to_surface( proj_loc ); 17334 17335 if( !ref_loc.about_equal( proj_loc ) ) 17336 { 17337 PRINT_ERROR( "Target location must project to all of the 'modify' surfaces at\n" 17338 " exactly the same location - the tweaked Vertex %d will move to this\n" 17339 " common (same) projected location, tweaking the modify surfaces with it.\n" 17340 " Given target location = %f, %f, %f\n" 17341 " Projected location on Surface %d = %f, %f, %f\n" 17342 " Projected location on Surface %d = %f, %f, %f\n", 17343 ref_vertex_ptr->id(), 17344 target_loc.x(), target_loc.y(), target_loc.z(), 17345 ref_surf_id, ref_loc.x(), ref_loc.y(), ref_loc.z(), 17346 ref_face_ptr->id(), proj_loc.x(), proj_loc.y(), proj_loc.z() ); 17347 17348 return CUBIT_FAILURE; 17349 } 17350 } 17351 17352 // It looks like the inputs are valid so get ready to do the tweak 17353 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 17354 { 17355 if( keep_old ) 17356 CubitUndo::save_state(); 17357 else 17358 CubitUndo::save_state_with_cubit_file( ref_vertex_list ); 17359 } 17360 17361 TBPoint *point_ptr = point_list.get(); 17362 17363 // Do tweak to target 17364 BodySM *new_bodysm_ptr; 17365 CubitStatus stat = gme_ptr->tweak_target( point_ptr, surface_list, 17366 ref_loc, 17367 new_bodysm_ptr, 17368 keep_old, preview ); 17369 17370 if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE ) 17371 if( stat == CUBIT_FAILURE ) 17372 CubitUndo::remove_last_undo(); 17373 17374 if( stat == CUBIT_FAILURE) 17375 return stat; 17376 17377 DLIList<BodySM*> new_bodysm_list; 17378 new_bodysm_list.append( new_bodysm_ptr ); 17379 DLIList<Body*> new_body_list; 17380 17381 if( preview == CUBIT_FALSE ) 17382 { 17383 // Update DAG 17384 stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list ); 17385 17386 if( CubitUndo::get_undo_enabled() ) 17387 { 17388 if( stat == CUBIT_FAILURE ) 17389 CubitUndo::remove_last_undo(); 17390 else if( keep_old ) 17391 CubitUndo::note_result_bodies( new_body_list ); 17392 } 17393 } 17394 17395 // Update graphics 17396 DLIList<Body*> moved_bodies(new_body_list); 17397 moved_bodies.intersect(old_body_list); 17398 while (moved_bodies.size()) 17399 moved_bodies.pop()->notify_sub_all_observers( GeometryEvent::GEOMETRY_MODIFIED ); 17400 17401 return stat; 17402 } 17403 17404 // KGM 17405 #if 0 17406 bool GeometryModifyTool::contains_intermediate_geometry(DLIList<RefFace*>& ref_face_list) const 17407 { 17408 for (int i = 0; i < ref_face_list.size(); i++) 17409 if (GeometryQueryTool::instance()-> 17410 contains_intermediate_geometry(ref_face_list.next(i))) 17411 return true; 17412 17413 return false; 17414 } 17415 #endif 17416 17417 /* 17418 //the following surface tool operations added by Tyronne Lim (CAT) ******************** 17419 CubitStatus GeometryModifyTool::create_net_surface( DLIList<Surface*>& ref_face_list, BodySM *& new_body, 17420 DLIList<DLIList<CubitVector*>*> &vec_lists_u, 17421 DLIList<DLIList<CubitVector*>*> &vec_lists_v, 17422 double net_tol, CubitBoolean heal ) 17423 { 17424 GeometryModifyEngine* GMEPtr = get_engine(ref_face_list.get()); 17425 return GMEPtr->create_net_surface( ref_face_list, new_body, vec_lists_u, vec_lists_v, net_tol, heal ); 17426 } */ 17427 17428 CubitStatus GeometryModifyTool::create_net_surface( DLIList<RefEdge*>& u_curves, DLIList<RefEdge*>& v_curves, 17429 double net_tol, CubitBoolean heal ) 17430 { 17431 DLIList<TopologyBridge*> bridge_list; 17432 DLIList<TopologyEntity*> entity_list; 17433 CAST_LIST_TO_PARENT( u_curves, entity_list ); 17434 17435 GeometryModifyEngine* GME_ptr = 17436 common_modify_engine( entity_list, bridge_list ); 17437 if(! GME_ptr ) 17438 { 17439 PRINT_ERROR("Cannot construct a Surface using entities that do " 17440 "not share a common GeometryModifyEngine.\n"); 17441 return CUBIT_FAILURE; 17442 } 17443 17444 DLIList<Curve*> curves_in_u(bridge_list.size()); 17445 CAST_LIST( bridge_list, curves_in_u, Curve ); 17446 17447 bridge_list.clean_out(); 17448 entity_list.clean_out(); 17449 CAST_LIST_TO_PARENT( v_curves, entity_list ); 17450 17451 GeometryModifyEngine* dummy_GME_ptr = 17452 common_modify_engine( entity_list, bridge_list ); 17453 if(! dummy_GME_ptr || dummy_GME_ptr != GME_ptr ) 17454 { 17455 PRINT_ERROR("Cannot construct a Surface using entities that do " 17456 "not share a common GeometryModifyEngine.\n"); 17457 return CUBIT_FAILURE; 17458 } 17459 17460 DLIList<Curve*> curves_in_v(bridge_list.size()); 17461 CAST_LIST( bridge_list, curves_in_v, Curve ); 17462 17463 BodySM *new_smbody = NULL; 17464 if( !GME_ptr->create_net_surface( curves_in_u, curves_in_v, new_smbody, net_tol, heal ) ) 17465 return CUBIT_FAILURE; 17466 17467 if (CubitUndo::get_undo_enabled()) 17468 CubitUndo::save_state(); 17469 17470 Body* new_body = NULL; 17471 new_body = GeometryQueryTool::instance()->make_Body( new_smbody ); 17472 if( new_body ) 17473 { 17474 if (CubitUndo::get_undo_enabled()) 17475 CubitUndo::note_result_body(new_body); 17476 17477 return CUBIT_SUCCESS; 17478 } 17479 else 17480 { 17481 if (CubitUndo::get_undo_enabled()) 17482 CubitUndo::remove_last_undo(); 17483 17484 return CUBIT_FAILURE; 17485 } 17486 } 17487 17488 CubitStatus GeometryModifyTool::create_offset_surface( RefFace* ref_face_ptr, double offset_distance ) 17489 { 17490 TopologyBridge *bridge_ptr = NULL; 17491 GeometryModifyEngine* GMEPtr = get_engine(ref_face_ptr, &bridge_ptr ); 17492 17493 Surface *tmp_surf = NULL; 17494 tmp_surf = CAST_TO( bridge_ptr, Surface ); 17495 17496 BodySM *new_smbody; 17497 if( !GMEPtr->create_offset_surface( tmp_surf, new_smbody, offset_distance ) ) 17498 return CUBIT_FAILURE; 17499 17500 if (CubitUndo::get_undo_enabled()) 17501 CubitUndo::save_state(); 17502 17503 Body* new_body = NULL; 17504 new_body = GeometryQueryTool::instance()->make_Body( new_smbody ); 17505 if( new_body ) 17506 { 17507 if (CubitUndo::get_undo_enabled()) 17508 CubitUndo::note_result_body(new_body); 17509 17510 return CUBIT_SUCCESS; 17511 } 17512 else 17513 { 17514 if (CubitUndo::get_undo_enabled()) 17515 CubitUndo::remove_last_undo(); 17516 17517 return CUBIT_FAILURE; 17518 } 17519 } 17520 17521 //----------------------------------------------------------------------------- 17522 // Purpose : This function creates a sheet body or bodies by offsetting 17523 // the given faces. An optional additional face list and double 17524 // list (must be same length) allow different offset distances 17525 // for different faces. Adjoining faces are extended or trimmed 17526 // to remain joined in the new sheet body. Radial faces that 17527 // cannot be so offset are removed and the resulting wound 17528 // healed by the surrounding faces. 17529 // 17530 // Special Notes : 17531 // 17532 // Creator : Steve Storm 17533 // 17534 // Creation Date : 05/04/08 17535 //----------------------------------------------------------------------------- 17536 CubitStatus 17537 GeometryModifyTool::create_offset_sheet( DLIList<RefFace*> &ref_face_list, 17538 double offset_distance, 17539 DLIList<RefFace*> *add_ref_face_list_ptr, 17540 DLIList<double> *add_offset_list_ptr, 17541 DLIList<Body*> &new_body_list, 17542 CubitBoolean preview ) 17543 { 17544 if( !ref_face_list.size() ) 17545 { 17546 return CUBIT_SUCCESS; 17547 } 17548 else 17549 { 17550 for (int i = 0; i < ref_face_list.size(); i++) 17551 { 17552 RefFace *temp = ref_face_list.get_and_step(); 17553 if (temp->get_surface_ptr()->is_cylindrical() == 16) 17554 { 17555 DLIList<Curve*> curves; 17556 CubitVector loc; 17557 double rad; 17558 temp->get_surface_ptr()->curves(curves); 17559 curves.reset(); 17560 int j = 0; 17561 while (curves.get()->geometry_type() != ELLIPSE_CURVE_TYPE && curves.get()->geometry_type() != ARC_CURVE_TYPE) 17562 { 17563 curves.step(); 17564 if (j == curves.size()) 17565 { 17566 break; 17567 } 17568 j++; 17569 } 17570 curves.get()->get_center_radius(loc, rad); 17571 if (offset_distance >= rad) 17572 { 17573 CubitVector norm, close, result; 17574 double angle; 17575 temp->get_surface_ptr()->closest_point(loc, &close, &norm); 17576 result.set(loc.x()-close.x(), loc.y()-close.y(), loc.z()-close.z()); 17577 angle = result.interior_angle(norm); 17578 if (angle < GEOMETRY_RESABS && angle > -GEOMETRY_RESABS) 17579 { 17580 PRINT_ERROR("Offset is greater than the radius of curvature for surface %i.\n", temp->id()); 17581 PRINT_WARNING("No body will be created for surface %i.\n", temp->id()); 17582 if (ref_face_list.size() > 1) 17583 { 17584 ref_face_list.remove_all_with_value(temp); 17585 } 17586 else 17587 { 17588 return CUBIT_FAILURE; 17589 } 17590 } 17591 } 17592 } 17593 } 17594 for (int i = 0; i < add_ref_face_list_ptr->size(); i++) 17595 { 17596 RefFace *temp = ref_face_list.get_and_step(); 17597 if (temp->get_surface_ptr()->is_cylindrical() == 16) 17598 { 17599 DLIList<Curve*> curves; 17600 CubitVector loc; 17601 double rad; 17602 temp->get_surface_ptr()->curves(curves); 17603 curves.reset(); 17604 while (curves.get()->geometry_type() != ELLIPSE_CURVE_TYPE && curves.get()->geometry_type() != ARC_CURVE_TYPE) 17605 { 17606 curves.step(); 17607 } 17608 curves.get()->get_center_radius(loc, rad); 17609 if (offset_distance >= rad) 17610 { 17611 CubitVector norm, close, result; 17612 double angle; 17613 temp->get_surface_ptr()->closest_point(loc, &close, &norm); 17614 result.set(loc.x()-close.x(), loc.y()-close.y(), loc.z()-close.z()); 17615 angle = result.interior_angle(norm); 17616 if (angle < GEOMETRY_RESABS && angle > -GEOMETRY_RESABS) 17617 { 17618 PRINT_ERROR("Offset is greater than the radius of curvature for surface %i.\n", temp->id()); 17619 PRINT_WARNING("No body will be created for surface %i.\n", temp->id()); 17620 add_ref_face_list_ptr->remove_all_with_value(temp); 17621 } 17622 } 17623 } 17624 } 17625 } 17626 17627 DLIList<RefFace*> all_ref_face_list(ref_face_list.size()); 17628 all_ref_face_list = ref_face_list; 17629 if( add_ref_face_list_ptr->size() ) 17630 all_ref_face_list += *add_ref_face_list_ptr; 17631 17632 // Check for virtual geometry 17633 DLIList<RefEntity*> ref_ent_list; 17634 CAST_LIST_TO_PARENT(all_ref_face_list, ref_ent_list); 17635 if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) ) 17636 { 17637 PRINT_ERROR("OFFSETTING surfaces containing virtual geometry is not\n" 17638 " allowed. Delete virtual geometry on these surfaces\n" 17639 " before operation.\n" ); 17640 return CUBIT_FAILURE; 17641 } 17642 17643 // Look for a common GeometryModifyEngine for all of the RefFaces 17644 int count = all_ref_face_list.size(); 17645 DLIList<TopologyBridge*> bridge_list(count); 17646 DLIList<TopologyEntity*> entity_list(count); 17647 CAST_LIST_TO_PARENT( all_ref_face_list, entity_list ); 17648 17649 GeometryModifyEngine* GME_ptr = 17650 common_modify_engine( entity_list, bridge_list ); 17651 if(! GME_ptr ) 17652 { 17653 PRINT_ERROR("Cannot construct offset sheet(s) using surfaces that\n" 17654 " do not share a common geometry engine.\n"); 17655 return CUBIT_FAILURE; 17656 } 17657 17658 // Get Surfaces from the RefFaces 17659 DLIList<Surface*> surface_list(ref_face_list.size()); 17660 int i; 17661 RefFace *ref_face_ptr; 17662 for( i=ref_face_list.size(); i--; ) 17663 { 17664 ref_face_ptr = ref_face_list.get_and_step(); 17665 surface_list.append( ref_face_ptr->get_surface_ptr() ); 17666 } 17667 17668 DLIList<Surface*> add_surf_list; 17669 if( add_ref_face_list_ptr->size() ) 17670 { 17671 for( i=add_ref_face_list_ptr->size(); i--; ) 17672 { 17673 ref_face_ptr = add_ref_face_list_ptr->get_and_step(); 17674 add_surf_list.append( ref_face_ptr->get_surface_ptr() ); 17675 } 17676 } 17677 17678 if (CubitUndo::get_undo_enabled() && !preview ) 17679 CubitUndo::save_state(); 17680 17681 CubitStatus status; 17682 DLIList<BodySM*> BodySM_list; 17683 if( add_surf_list.size() ) 17684 { 17685 status = GME_ptr->create_offset_sheet( surface_list, offset_distance, &add_surf_list, 17686 add_offset_list_ptr, BodySM_list, preview ); 17687 } 17688 else 17689 { 17690 status = GME_ptr->create_offset_sheet( surface_list, offset_distance, NULL, 17691 NULL, BodySM_list, preview ); 17692 } 17693 17694 if( status == CUBIT_FAILURE || !BodySM_list.size() ) 17695 { 17696 if(CubitUndo::get_undo_enabled() && !preview ) 17697 CubitUndo::remove_last_undo(); 17698 return CUBIT_FAILURE; 17699 } 17700 17701 BodySM *bodysm_ptr; 17702 Body* body_ptr; 17703 for( i=BodySM_list.size(); i--; ) 17704 { 17705 DLIList<Surface*> surfs; 17706 bodysm_ptr = BodySM_list.get_and_step(); 17707 bodysm_ptr->surfaces(surfs); 17708 if (!surfs.size()) 17709 { 17710 PRINT_WARNING("Empty body created. Body deleted.\n"); 17711 PRINT_WARNING("Empty body likely due to an offset larger than the radius of curvature of a surface.\n"); 17712 bodysm_ptr->get_geometry_query_engine()->delete_solid_model_entities(bodysm_ptr); 17713 break; 17714 } 17715 17716 body_ptr = GeometryQueryTool::instance()->make_Body( bodysm_ptr ); 17717 if( body_ptr ) 17718 new_body_list.append( body_ptr ); 17719 } 17720 17721 if( new_body_list.size() ) 17722 { 17723 if(CubitUndo::get_undo_enabled() && !preview ) 17724 CubitUndo::note_result_bodies(new_body_list); 17725 return CUBIT_SUCCESS; 17726 } 17727 else 17728 { 17729 if(CubitUndo::get_undo_enabled() && !preview ) 17730 CubitUndo::remove_last_undo(); 17731 return CUBIT_FAILURE; 17732 } 17733 } 17734 17735 CubitStatus 17736 GeometryModifyTool::create_offset_body( Body *body_ptr, Body *&new_body, 17737 double offset_distance ) 17738 { 17739 GeometryModifyEngine* GMEPtr = get_engine(body_ptr); 17740 17741 BodySM *body_sm = body_ptr->get_body_sm_ptr(); 17742 if (!body_sm) 17743 { 17744 PRINT_ERROR("Body %d is invalid -- no attached BodySM.\n", body_ptr->id()); 17745 return CUBIT_FAILURE; 17746 } 17747 17748 BodySM *new_body_sm; 17749 if( !GMEPtr->create_offset_body( body_sm, new_body_sm, offset_distance ) ) 17750 return CUBIT_FAILURE; 17751 17752 if (CubitUndo::get_undo_enabled()) 17753 CubitUndo::save_state(); 17754 17755 new_body = GeometryQueryTool::instance()->make_Body( new_body_sm ); 17756 17757 if( new_body ) 17758 { 17759 if (CubitUndo::get_undo_enabled()) 17760 CubitUndo::note_result_body(new_body); 17761 17762 return CUBIT_SUCCESS; 17763 } 17764 else 17765 { 17766 if (CubitUndo::get_undo_enabled()) 17767 CubitUndo::remove_last_undo(); 17768 17769 return CUBIT_FAILURE; 17770 } 17771 } 17772 17773 CubitStatus GeometryModifyTool::create_skin_surface( DLIList<RefEdge*>& ref_edges, Body*& new_body, 17774 DLIList<RefEdge*>& guides) 17775 { 17776 DLIList<TopologyBridge*> bridge_list; 17777 DLIList<TopologyEntity*> entity_list; 17778 CAST_LIST_TO_PARENT( ref_edges, entity_list ); 17779 17780 DLIList<TopologyBridge*> guide_bridge_list; 17781 DLIList<TopologyEntity*> guide_entity_list; 17782 CAST_LIST_TO_PARENT(guides, guide_entity_list); 17783 17784 if (ref_edges.size() < 2) 17785 { 17786 PRINT_ERROR("Must specify at least 2 curves to create a skinned surface.\n"); 17787 return CUBIT_FAILURE; 17788 } 17789 17790 GeometryModifyEngine* GME_ptr = 17791 common_modify_engine( entity_list, bridge_list ); 17792 if(! GME_ptr ) 17793 { 17794 PRINT_ERROR("Cannot construct a Surface using entities that do " 17795 "not share a common GeometryModifyEngine.\n"); 17796 return CUBIT_FAILURE; 17797 } 17798 17799 if (guides.size() > 0) 17800 { 17801 GeometryModifyEngine* GME_ptr2 = 17802 common_modify_engine( guide_entity_list, guide_bridge_list ); 17803 if (GME_ptr != GME_ptr2) 17804 { 17805 PRINT_ERROR("Performing create skin with geometry from\n" 17806 "different modeling engines is not allowed.\n"); 17807 return CUBIT_FAILURE; 17808 } 17809 } 17810 17811 DLIList<Curve*> curves_to_skin(bridge_list.size()); 17812 CAST_LIST( bridge_list, curves_to_skin, Curve ); 17813 17814 DLIList<Curve*> guide_curves(guide_bridge_list.size()); 17815 CAST_LIST(guide_bridge_list, guide_curves, Curve); 17816 17817 BodySM *new_body_sm = NULL; 17818 if( !GME_ptr->create_skin_surface( curves_to_skin, new_body_sm, guide_curves ) ) 17819 return CUBIT_FAILURE; 17820 17821 if (CubitUndo::get_undo_enabled()) 17822 CubitUndo::save_state(); 17823 17824 new_body = NULL; 17825 new_body = GeometryQueryTool::instance()->make_Body( new_body_sm ); 17826 17827 if( new_body ) 17828 { 17829 if (CubitUndo::get_undo_enabled()) 17830 CubitUndo::note_result_body(new_body); 17831 17832 return CUBIT_SUCCESS; 17833 } 17834 else 17835 { 17836 if (CubitUndo::get_undo_enabled()) 17837 CubitUndo::remove_last_undo(); 17838 17839 return CUBIT_FAILURE; 17840 } 17841 } 17842 CubitStatus GeometryModifyTool::loft_surfaces_to_body(DLIList<RefFace*> &surfaces, 17843 DLIList<double> &takeoff_factor_list, 17844 DLIList<RefFace*> &takeoff_vector_surface_list, 17845 DLIList<CubitVector> &surface_takeoff_vector_list, 17846 DLIList<RefEdge*> &takeoff_vector_curve_list, 17847 DLIList<CubitVector> &curve_takeoff_vector_list, 17848 DLIList<RefEdge*> &guides, 17849 DLIList<RefVertex*> &match_vertices_list, 17850 Body*& new_body, 17851 CubitBoolean global_guides, 17852 CubitBoolean closed, 17853 CubitBoolean show_matching_curves, 17854 CubitBoolean preview 17855 ) 17856 { 17857 DLIList<Surface*> loft_surfaces; 17858 17859 // Get engine and correspoding geom entities 17860 GeometryModifyEngine* result_ptr; 17861 result_ptr = common_modify_engine( surfaces, loft_surfaces ); 17862 if (!result_ptr) 17863 { 17864 PRINT_ERROR("Loft surfaces on volumes containing surfaces from different\n" 17865 " geometry engines is not allowed.\n"); 17866 return CUBIT_FAILURE; 17867 } 17868 17869 17870 DLIList<Curve*> loft_guide_curves; 17871 // Get engine and correspoding geom entities 17872 if(guides.size()) 17873 { 17874 result_ptr = common_modify_engine( guides, loft_guide_curves ); 17875 if (!result_ptr) 17876 { 17877 PRINT_ERROR("Loft guide curves containing curves from different\n" 17878 " geometry engines is not allowed.\n"); 17879 return CUBIT_FAILURE; 17880 } 17881 } 17882 17883 17884 17885 DLIList<TBPoint*> loft_matched_points; 17886 // Get engine and correspoding geom entities 17887 if(match_vertices_list.size()) 17888 { 17889 result_ptr = common_modify_engine( match_vertices_list, loft_matched_points ); 17890 if (!result_ptr) 17891 { 17892 PRINT_ERROR("Loft matched vertices containing points from different\n" 17893 " geometry engines is not allowed.\n"); 17894 return CUBIT_FAILURE; 17895 } 17896 } 17897 17898 DLIList<Surface*> loft_takeoff_surfaces; 17899 17900 if(takeoff_vector_surface_list.size()) 17901 { 17902 // Get engine and correspoding geom entities 17903 GeometryModifyEngine* result_ptr; 17904 result_ptr = common_modify_engine( takeoff_vector_surface_list, loft_takeoff_surfaces ); 17905 if (!result_ptr) 17906 { 17907 PRINT_ERROR("Loft takeoff surfaces on volumes containing surfaces from different\n" 17908 " geometry engines is not allowed.\n"); 17909 return CUBIT_FAILURE; 17910 } 17911 } 17912 17913 DLIList<Curve*> loft_takeoff_curves; 17914 17915 if(takeoff_vector_curve_list.size()) 17916 { 17917 // Get engine and correspoding geom entities 17918 GeometryModifyEngine* result_ptr; 17919 result_ptr = common_modify_engine( takeoff_vector_curve_list, loft_takeoff_curves ); 17920 if (!result_ptr) 17921 { 17922 PRINT_ERROR("Loft takeoff surfaces on volumes containing surfaces from different\n" 17923 " geometry engines is not allowed.\n"); 17924 return CUBIT_FAILURE; 17925 } 17926 } 17927 17928 17929 BodySM* new_body_sm = 0; 17930 17931 if( CubitUndo::get_undo_enabled() ) 17932 CubitUndo::save_state(); 17933 17934 CubitStatus result = result_ptr->loft_surfaces_to_body( 17935 loft_surfaces, 17936 takeoff_factor_list, 17937 loft_takeoff_surfaces, 17938 surface_takeoff_vector_list, 17939 loft_takeoff_curves, 17940 curve_takeoff_vector_list, 17941 loft_guide_curves, 17942 loft_matched_points, 17943 new_body_sm, 17944 global_guides, 17945 closed, 17946 show_matching_curves, 17947 preview); 17948 17949 if(result && new_body_sm) 17950 { 17951 new_body = GeometryQueryTool::instance()->make_Body(new_body_sm); 17952 17953 if( CubitUndo::get_undo_enabled() ) 17954 CubitUndo::note_result_body(new_body); 17955 } 17956 else 17957 { 17958 if( CubitUndo::get_undo_enabled() ) 17959 CubitUndo::remove_last_undo(); 17960 } 17961 return result; 17962 } 17963 17964 17965 //CubitStatus GeometryModifyTool::loft_surfaces_to_body( RefFace *face1, const double &takeoff1, 17966 // RefFace *face2, const double &takeoff2, 17967 // DLIList<RefEdge*> &guides, 17968 // Body*& new_body, 17969 // CubitBoolean arc_length_option, CubitBoolean twist_option, 17970 // CubitBoolean align_direction, CubitBoolean perpendicular, 17971 // CubitBoolean simplify_option) 17972 //{ 17973 // 17974 // DLIList<RefFace*> loft_faces; 17975 // loft_faces.append(face1); 17976 // loft_faces.append(face2); 17977 // DLIList<Surface*> loft_surfaces; 17978 // 17979 // // Get engine and correspoding geom entities 17980 // GeometryModifyEngine* result_ptr; 17981 // result_ptr = common_modify_engine( loft_faces, loft_surfaces ); 17982 // if (!result_ptr) 17983 // { 17984 // PRINT_ERROR("Loft surfaces on volumes containing surfaces from different\n" 17985 // " geometry engines is not allowed.\n"); 17986 // return CUBIT_FAILURE; 17987 // } 17988 // 17989 // if(2!=loft_surfaces.size()) 17990 // return CUBIT_FAILURE; 17991 // 17992 // 17993 // 17994 // DLIList<Curve*> loft_curves; 17995 // 17996 // // Get engine and correspoding geom entities 17997 // result_ptr = common_modify_engine( guides, loft_curves ); 17998 // if (!result_ptr) 17999 // { 18000 // PRINT_ERROR("Loft surfaces on volumes containing surfaces from different\n" 18001 // " geometry engines is not allowed.\n"); 18002 // return CUBIT_FAILURE; 18003 // } 18004 // 18005 // 18006 // std::vector<Curve*> guide_edges; 18007 // for(int i=0;i<loft_curves.size();i++) 18008 // { 18009 // guide_edges.push_back(loft_curves[i]); 18010 // } 18011 // 18012 // 18013 // 18014 // 18015 // loft_surfaces.reset(); 18016 // BodySM* new_body_sm = 0; 18017 // 18018 // if( CubitUndo::get_undo_enabled() ) 18019 // CubitUndo::save_state(); 18020 // 18021 // CubitStatus result = result_ptr->loft_surfaces_to_body( 18022 // loft_surfaces.get_and_step(), 18023 // takeoff1, 18024 // loft_surfaces.get_and_step(), 18025 // takeoff2, 18026 // guide_edges, 18027 // new_body_sm, 18028 // arc_length_option, 18029 // twist_option, 18030 // align_direction, 18031 // perpendicular, 18032 // simplify_option); 18033 // 18034 // if(result && new_body_sm) 18035 // { 18036 // new_body = GeometryQueryTool::instance()->make_Body(new_body_sm); 18037 // 18038 // if( CubitUndo::get_undo_enabled() ) 18039 // CubitUndo::note_result_body(new_body); 18040 // } 18041 // else 18042 // { 18043 // if( CubitUndo::get_undo_enabled() ) 18044 // CubitUndo::remove_last_undo(); 18045 // } 18046 // return result; 18047 //} 18048 // 18049 // 18050 18051 //CubitStatus GeometryModifyTool::loft_surfaces_to_body( RefFace *face1, const double &takeoff1, 18052 // RefFace *face2, const double &takeoff2, 18053 // Body*& new_body, 18054 // CubitBoolean arc_length_option, CubitBoolean twist_option, 18055 // CubitBoolean align_direction, CubitBoolean perpendicular, 18056 // CubitBoolean simplify_option) 18057 //{ 18058 // 18059 // DLIList<RefFace*> loft_faces; 18060 // loft_faces.append(face1); 18061 // loft_faces.append(face2); 18062 // DLIList<Surface*> loft_surfaces; 18063 // 18064 // // Get engine and correspoding geom entities 18065 // GeometryModifyEngine* result_ptr; 18066 // result_ptr = common_modify_engine( loft_faces, loft_surfaces ); 18067 // if (!result_ptr) 18068 // { 18069 // PRINT_ERROR("Loft surfaces on volumes containing surfaces from different\n" 18070 // " geometry engines is not allowed.\n"); 18071 // return CUBIT_FAILURE; 18072 // } 18073 // 18074 // if(2!=loft_surfaces.size()) 18075 // return CUBIT_FAILURE; 18076 // 18077 // loft_surfaces.reset(); 18078 // BodySM* new_body_sm = 0; 18079 // 18080 // if( CubitUndo::get_undo_enabled() ) 18081 // CubitUndo::save_state(); 18082 // 18083 // 18084 // CubitStatus result = result_ptr->loft_surfaces_to_body( 18085 // loft_surfaces[0], 18086 // takeoff1, 18087 // loft_surfaces[1], 18088 // takeoff2, 18089 // new_body_sm, 18090 // arc_length_option, 18091 // twist_option, 18092 // align_direction, 18093 // perpendicular, 18094 // simplify_option); 18095 // 18096 // 18097 // 18098 // if(result && new_body_sm) 18099 // { 18100 // new_body = GeometryQueryTool::instance()->make_Body(new_body_sm); 18101 // 18102 // if( CubitUndo::get_undo_enabled() ) 18103 // CubitUndo::note_result_body(new_body); 18104 // } 18105 // else 18106 // { 18107 // if( CubitUndo::get_undo_enabled() ) 18108 // CubitUndo::remove_last_undo(); 18109 // } 18110 // return result; 18111 //} 18112 18113 CubitStatus GeometryModifyTool::create_surface( DLIList<RefVertex*> &vert_list, 18114 Body *&new_body, RefFace *on_surface ) 18115 { 18116 //determine which vertices are free and which are not... 18117 //copy ones that are not 18118 vert_list.reset(); 18119 DLIList<TBPoint*> points; 18120 GeometryModifyEngine *GMEPtr = get_engine( vert_list.get()->get_point_ptr() ); 18121 18122 DLIList<RefVertex*> free_ref_vertices; 18123 int i; 18124 for( i=vert_list.size(); i--; ) 18125 { 18126 RefVertex *tmp_vert = vert_list.get_and_step(); 18127 18128 if( tmp_vert->num_parent_ref_entities() == 0 ) 18129 free_ref_vertices.append( tmp_vert ); 18130 18131 TBPoint *tmp_point = tmp_vert->get_point_ptr(); 18132 if( GMEPtr != get_engine( tmp_point ) ) 18133 { 18134 PRINT_INFO("Vertices are not from same modeling engine.\n"); 18135 return CUBIT_FAILURE; 18136 } 18137 18138 if( tmp_vert->get_parents() == 0 ) 18139 { 18140 points.append( tmp_point ); 18141 } 18142 else 18143 { 18144 TBPoint *new_point = GMEPtr->make_Point( tmp_vert->coordinates() ); 18145 points.append( new_point ); 18146 } 18147 } 18148 18149 if( on_surface ) 18150 { 18151 if( GMEPtr != get_engine( on_surface->get_surface_ptr() ) ) 18152 { 18153 PRINT_INFO("Surface and Vertices are not from same modeling engine.\n"); 18154 return CUBIT_FAILURE; 18155 } 18156 } 18157 18158 if(CubitUndo::get_undo_enabled()) 18159 { 18160 if( free_ref_vertices.size() ) 18161 CubitUndo::save_state_with_cubit_file( free_ref_vertices ); 18162 else 18163 CubitUndo::save_state(); 18164 } 18165 18166 18167 BodySM* body_sm = NULL; 18168 Surface *on_surf = NULL; 18169 18170 if( on_surface ) 18171 on_surf = on_surface->get_surface_ptr(); 18172 18173 CubitStatus stat = GMEPtr->create_surface( points, body_sm, on_surf ); 18174 18175 if( stat == CUBIT_FAILURE ) 18176 { 18177 if (CubitUndo::get_undo_enabled()) 18178 CubitUndo::remove_last_undo(); 18179 return stat; 18180 } 18181 18182 if( body_sm ) 18183 new_body = GeometryQueryTool::instance()->make_Body(body_sm); 18184 18185 if (new_body) 18186 { 18187 if (CubitUndo::get_undo_enabled()) 18188 CubitUndo::note_result_body(new_body); 18189 18190 stat = CUBIT_SUCCESS; 18191 } 18192 else 18193 { 18194 if (CubitUndo::get_undo_enabled()) 18195 CubitUndo::remove_last_undo(); 18196 18197 stat = CUBIT_FAILURE; 18198 } 18199 18200 for( i=free_ref_vertices.size(); i--; ) 18201 { 18202 RefVertex *free_vertex = free_ref_vertices.get_and_step(); 18203 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOP_LEVEL_ENTITY_DESTRUCTED, free_vertex)); 18204 CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_DELETED, free_vertex ); 18205 GeometryQueryTool::instance()->history().add_event(evt); 18206 } 18207 18208 return stat; 18209 } 18210 18211 CubitStatus GeometryModifyTool::create_surface( DLIList<CubitVector*>& vec_list, 18212 Body *&new_body, 18213 RefFace *ref_face_ptr, 18214 CubitBoolean project_points ) 18215 { 18216 GeometryModifyEngine* GMEPtr = gmeList.get(); 18217 if( ref_face_ptr ) 18218 { 18219 if( GMEPtr != get_engine(ref_face_ptr) ) 18220 { 18221 PRINT_ERROR("Geometry engine of Surface %d is not the active geometry engine.\n", ref_face_ptr->id() ); 18222 PRINT_INFO(" Use command \"Set Geometry Engine ...\" to set to correct engine.\n"); 18223 return CUBIT_FAILURE; 18224 } 18225 } 18226 BodySM* body_sm = NULL; 18227 Surface *project_to_surface = NULL; 18228 if( ref_face_ptr ) 18229 project_to_surface = ref_face_ptr->get_surface_ptr(); 18230 CubitStatus stat = GMEPtr->create_surface( vec_list, body_sm, project_to_surface, project_points ); 18231 18232 if( stat == CUBIT_FAILURE ) 18233 return stat; 18234 18235 if (CubitUndo::get_undo_enabled()) 18236 CubitUndo::save_state(); 18237 18238 if( body_sm ) 18239 new_body = GeometryQueryTool::instance()->make_Body(body_sm); 18240 18241 if (new_body) 18242 { 18243 if (CubitUndo::get_undo_enabled()) 18244 CubitUndo::note_result_body(new_body); 18245 18246 stat = CUBIT_SUCCESS; 18247 } 18248 else 18249 { 18250 if (CubitUndo::get_undo_enabled()) 18251 CubitUndo::remove_last_undo(); 18252 18253 stat = CUBIT_FAILURE; 18254 } 18255 return stat; 18256 } 18257 18258 CubitStatus GeometryModifyTool::create_weld_surface( CubitVector &root, 18259 RefFace *ref_face1, 18260 double leg1, 18261 RefFace *ref_face2, 18262 double leg2, 18263 Body *&new_body ) 18264 { 18265 GeometryModifyEngine* GMEPtr; 18266 DLIList<RefFace*> ref_faces; 18267 ref_faces.append(ref_face1); 18268 ref_faces.append(ref_face2); 18269 DLIList<Surface*> surfaces; 18270 18271 GMEPtr = common_modify_engine(ref_faces, surfaces); 18272 if (!GMEPtr) 18273 { 18274 PRINT_ERROR("Loft surfaces on volumes containing surfaces from different\n" 18275 " geometry engines is not allowed.\n"); 18276 return CUBIT_FAILURE; 18277 } 18278 18279 if (CubitUndo::get_undo_enabled()) 18280 CubitUndo::save_state(); 18281 18282 surfaces.reset(); 18283 BodySM* new_body_sm = 0; 18284 CubitStatus result = GMEPtr->create_weld_surface( 18285 root, 18286 surfaces.get_and_step(), 18287 leg1, 18288 surfaces.get_and_step(), 18289 leg2, 18290 new_body_sm ); 18291 18292 if(result && new_body_sm) 18293 { 18294 new_body = GeometryQueryTool::instance()->make_Body(new_body_sm); 18295 if (new_body) 18296 { 18297 if (CubitUndo::get_undo_enabled()) 18298 CubitUndo::note_result_body(new_body); 18299 } 18300 else 18301 { 18302 if (CubitUndo::get_undo_enabled()) 18303 CubitUndo::remove_last_undo(); 18304 } 18305 } 18306 return result; 18307 } 18308 //end of surface tool operations ****************************************************** 18309 18310 //------------------------------------------------------------------------- 18311 // Purpose : Remove entity names from dead entities. 18312 // 18313 // Special Notes : 18314 // 18315 // Creator : Jason Kraftcheck 18316 // 18317 // Creation Date : 12/08/03 18318 //------------------------------------------------------------------------- 18319 void GeometryModifyTool::remove_dead_entity_names( RefEntity* entity ) const 18320 { 18321 TopologyEntity* topo_ent = dynamic_cast<TopologyEntity*>(entity); 18322 if (topo_ent->bridge_manager()->topology_bridge() == NULL) 18323 RefEntityName::instance()->remove_refentity_name( entity, CUBIT_TRUE ); 18324 18325 DLIList<RefEntity*> children; 18326 entity->get_child_ref_entities(children); 18327 children.last(); 18328 for (int i = children.size(); i--; ) 18329 { 18330 //PRINT_INFO("Removing dead entity on %s %d\n", children.get()->class_name(), children.get()->id() ); 18331 remove_dead_entity_names( children.step_and_get() ); 18332 } 18333 } 18334 18335 //------------------------------------------------------------------------- 18336 // Purpose : Destroy or update modified body, as appropriate. 18337 // 18338 // Special Notes : 18339 // 18340 // Creator : Jason Kraftcheck 18341 // 18342 // Creation Date : 12/08/03 18343 //------------------------------------------------------------------------- 18344 Body* GeometryModifyTool::update_body( Body* body ) const 18345 { 18346 BodySM* body_sm = body->get_body_sm_ptr(); 18347 if (body_sm) 18348 return GeometryQueryTool::instance()->make_Body(body_sm); 18349 18350 GeometryQueryTool::instance()->destroy_dead_entity(body); 18351 return 0; 18352 } 18353 18354 CubitStatus GeometryModifyTool::tolerant_imprint( DLIList<RefFace*> &ref_faces, 18355 DLIList<RefEdge*> &ref_edge_list, 18356 DLIList<Body*> &new_bodies, 18357 bool merge ) 18358 { 18359 if( ref_faces.size() > 2 ) 18360 return CUBIT_FAILURE; 18361 18362 ref_faces.reset(); 18363 RefFace *face1 = ref_faces.get_and_step(); 18364 RefFace *face2 = ref_faces.get_and_step(); 18365 18366 if(ref_edge_list.size() > 0) 18367 { 18368 //collect all the bodies containing any edge on these 2 surfaces 18369 //so you can merge them afterward 18370 DLIList<Body*> bodies_to_merge; 18371 if( merge ) 18372 { 18373 DLIList<RefEdge*> tmp_edges; 18374 face1->ref_edges( tmp_edges); 18375 18376 int j; 18377 for( j=tmp_edges.size(); j--; ) 18378 { 18379 RefEdge *tmp_edge = tmp_edges.get_and_step(); 18380 DLIList<Body*> body_list; 18381 tmp_edge->bodies( body_list ); 18382 bodies_to_merge += body_list; 18383 } 18384 18385 for( j=ref_edge_list.size(); j--; ) 18386 { 18387 RefEdge *tmp_edge = ref_edge_list.get_and_step(); 18388 DLIList<Body*> body_list; 18389 tmp_edge->bodies( body_list ); 18390 bodies_to_merge += body_list; 18391 } 18392 18393 tmp_edges.clean_out(); 18394 face2->ref_edges( tmp_edges ); 18395 18396 for( j=tmp_edges.size(); j--; ) 18397 { 18398 RefEdge *tmp_edge = tmp_edges.get_and_step(); 18399 DLIList<Body*> body_list; 18400 tmp_edge->bodies( body_list ); 18401 bodies_to_merge += body_list; 18402 } 18403 bodies_to_merge.uniquify_ordered(); 18404 } 18405 18406 DLIList<RefEdge*> edges_to_imprint_onto_face1; 18407 DLIList<RefEdge*> edges_to_imprint_onto_face2; 18408 18409 //sort edges... 18410 //edges on face1 and not on face2 will be imprinted on face2 18411 //edges on face2 and not on face1 will be imprinted on face1 18412 int i; 18413 for(i=ref_edge_list.size(); i--; ) 18414 { 18415 RefEdge *tmp_edge = ref_edge_list.get_and_step(); 18416 DLIList<RefFace*> tmp_faces; 18417 tmp_edge->ref_faces( tmp_faces ); 18418 18419 if( tmp_faces.move_to( face1 ) && !tmp_faces.move_to( face2 ) ) 18420 edges_to_imprint_onto_face2.append( tmp_edge ); 18421 else if( tmp_faces.move_to( face2 ) && !tmp_faces.move_to( face1 ) ) 18422 edges_to_imprint_onto_face1.append( tmp_edge ); 18423 else 18424 PRINT_ERROR("Will not imprint curve %d onto either surface.\n", tmp_edge->id() ); 18425 } 18426 18427 //if there are edges to impint onto both surfaces 18428 if( edges_to_imprint_onto_face1.size() && 18429 edges_to_imprint_onto_face2.size() ) 18430 { 18431 //get the modify engine 18432 DLIList<Surface*> surf_list( 1 ); 18433 DLIList<Curve*> curve_list( edges_to_imprint_onto_face2.size() ); 18434 DLIList<RefFace*> ref_face_list( 1 ); 18435 ref_face_list.append( face2 ); 18436 GeometryModifyEngine* gme = common_modify_engine( ref_face_list, 18437 edges_to_imprint_onto_face2, 18438 surf_list, 18439 curve_list ); 18440 if ( !gme ) 18441 { 18442 PRINT_ERROR("Performing IMPRINT with entities containing geometry from\n" 18443 "different modeling engines is not allowed.\n" ); 18444 return CUBIT_FAILURE; 18445 } 18446 18447 //copy the specified boundary curves of face1 to imprint onto face2... 18448 //these could be stale after we imprint face1 18449 DLIList<Curve*> copied_curves; 18450 for(i=curve_list.size(); i--; ) 18451 { 18452 Curve *copied_curve = gme->make_Curve( curve_list.get_and_step() ); 18453 copied_curves.append( copied_curve ); 18454 } 18455 18456 if( CubitUndo::get_undo_enabled() ) 18457 CubitUndo::save_state_with_cubit_file( ref_faces ); 18458 18459 //do the imprint onto face1 18460 Body *new_body = NULL; 18461 CubitStatus status; 18462 status = tolerant_imprint( face1, edges_to_imprint_onto_face1, new_body ); 18463 18464 //if we failed...get out 18465 if( status == CUBIT_FAILURE ) 18466 { 18467 //delete the copied curves 18468 for( i=copied_curves.size(); i--; ) 18469 gme->get_gqe()->delete_solid_model_entities( copied_curves.get_and_step() ); 18470 18471 if( CubitUndo::get_undo_enabled() ) 18472 CubitUndo::remove_last_undo(); 18473 18474 return CUBIT_FAILURE; 18475 } 18476 18477 DLIList<Body*> original_body_list; 18478 face2->bodies( original_body_list ); 18479 18480 //get the Surface* ptr 18481 Surface *surface2 = face2->get_surface_ptr(); 18482 18483 DLIList<BodySM*> body_sm_list; 18484 for(i=original_body_list.size(); i--;) 18485 body_sm_list.append(original_body_list.get_and_step()->get_body_sm_ptr()); 18486 18487 int process_composites = 0; 18488 if(contains_composites(original_body_list)) 18489 process_composites = 1; 18490 18491 if(process_composites) 18492 { 18493 // Push virtual attributes down to solid model topology before 18494 // doing the imprint. 18495 do_attribute_setup(); 18496 push_attributes_before_modify(body_sm_list); 18497 // This must be done after pushing the vg atts because it uses them. 18498 push_imprint_attributes_before_modify(body_sm_list); 18499 } 18500 18501 //do the imprint onto face2 18502 BodySM *new_bodysm = NULL; 18503 DLIList<TopologyBridge*> temporary_bridges; 18504 status = gme->tolerant_imprint_surface_with_curves( surface2, copied_curves, temporary_bridges, new_bodysm); 18505 temporary_bridges.uniquify_ordered(); 18506 while(temporary_bridges.size()) 18507 { 18508 TopologyBridge* bridge = temporary_bridges.pop(); 18509 bridge->get_geometry_query_engine()->delete_topology_bridge(bridge); 18510 } 18511 18512 DLIList<BodySM*> new_body_list; 18513 if(new_bodysm) 18514 new_body_list.append(new_bodysm); 18515 18516 18517 //delete the copied curves 18518 for( i=copied_curves.size(); i--; ) 18519 gme->get_gqe()->delete_solid_model_entities( copied_curves.get_and_step() ); 18520 18521 if( status == CUBIT_FAILURE ) 18522 { 18523 if( CubitUndo::get_undo_enabled() ) 18524 CubitUndo::remove_last_undo(); 18525 18526 if(process_composites) 18527 { 18528 remove_pushed_attributes(new_body_list, original_body_list); 18529 do_attribute_cleanup(); 18530 } 18531 18532 return CUBIT_FAILURE; 18533 } 18534 else 18535 { 18536 if(process_composites) 18537 { 18538 // Analyze the results and adjust virtual attributes as necessary. 18539 DLIList<TopologyBridge*> tb_list; 18540 CAST_LIST(new_body_list, tb_list, TopologyBridge); 18541 GeometryQueryTool::instance()->ige_attribute_after_imprinting(tb_list, original_body_list); 18542 18543 // Clean up attributes. 18544 remove_imprint_attributes_after_modify(body_sm_list, new_body_list); 18545 18546 // Restore the virtual geometry. 18547 restore_vg_after_modify(new_body_list, original_body_list, gme); 18548 remove_pushed_attributes(new_body_list, original_body_list); 18549 } 18550 } 18551 18552 DLIList<BodySM*> new_bodies; 18553 new_bodies.append( new_bodysm ); 18554 DLIList<Body*> result_bodies; 18555 status = finish_sm_op( original_body_list, new_bodies, result_bodies ); 18556 18557 if(process_composites) 18558 do_attribute_cleanup(); 18559 18560 if( status == CUBIT_FAILURE ) 18561 { 18562 if( CubitUndo::get_undo_enabled() ) 18563 CubitUndo::remove_last_undo(); 18564 return CUBIT_FAILURE; 18565 } 18566 } 18567 //user specified edges that will only imprint onto face1...do it anyway 18568 else if( edges_to_imprint_onto_face1.size() ) 18569 { 18570 if( CubitUndo::get_undo_enabled() ) 18571 { 18572 DLIList<RefFace*> tmp_faces(1); 18573 tmp_faces.append( face1 ); 18574 CubitUndo::save_state_with_cubit_file( tmp_faces ); 18575 } 18576 18577 bool undo_enabled = CubitUndo::get_undo_enabled(); 18578 CubitUndo::set_undo_enabled( false ); 18579 18580 Body *new_body = NULL; 18581 CubitStatus stat = tolerant_imprint( face1, edges_to_imprint_onto_face1, 18582 new_body, merge ); 18583 18584 if( undo_enabled ) 18585 CubitUndo::set_undo_enabled( true ); 18586 18587 if( CubitUndo::get_undo_enabled() ) 18588 { 18589 if( stat == CUBIT_FAILURE ) 18590 CubitUndo::remove_last_undo(); 18591 } 18592 18593 return stat; 18594 } 18595 //user specified edges that will only imprint onto face2...do it anyway 18596 else if( edges_to_imprint_onto_face2.size() ) 18597 { 18598 if( CubitUndo::get_undo_enabled() ) 18599 { 18600 DLIList<RefFace*> tmp_faces(1); 18601 tmp_faces.append( face2 ); 18602 CubitUndo::save_state_with_cubit_file( tmp_faces ); 18603 } 18604 18605 bool undo_enabled = CubitUndo::get_undo_enabled(); 18606 CubitUndo::set_undo_enabled( false ); 18607 18608 Body *new_body = NULL; 18609 CubitStatus stat = tolerant_imprint( face2, edges_to_imprint_onto_face2, 18610 new_body, merge ); 18611 18612 if( undo_enabled ) 18613 CubitUndo::set_undo_enabled( true ); 18614 18615 if( CubitUndo::get_undo_enabled() ) 18616 { 18617 if( stat == CUBIT_FAILURE ) 18618 CubitUndo::remove_last_undo(); 18619 } 18620 18621 return stat; 18622 } 18623 18624 if( merge ) 18625 MergeTool::instance()->merge_bodies( bodies_to_merge ); 18626 } 18627 else 18628 { 18629 DLIList<RefFace*> faces_not_to_merge; 18630 Body *body1 = face1->body(); 18631 Body *body2 = face2->body(); 18632 18633 if(merge) 18634 { 18635 DLIList<RefFace*> tmp_faces; 18636 body1->ref_faces(tmp_faces); 18637 if(tmp_faces.move_to(face1)) 18638 tmp_faces.extract(); 18639 faces_not_to_merge = tmp_faces; 18640 18641 tmp_faces.clean_out(); 18642 body2->ref_faces(tmp_faces); 18643 if(tmp_faces.move_to(face2)) 18644 tmp_faces.extract(); 18645 faces_not_to_merge += tmp_faces; 18646 } 18647 18648 //get the modify engine 18649 DLIList<Surface*> surf_list( 1 ); 18650 DLIList<RefFace*> ref_face_list( 2 ); 18651 ref_face_list.append( face1 ); 18652 ref_face_list.append( face2 ); 18653 GeometryModifyEngine* gme = common_modify_engine( ref_face_list, surf_list); 18654 18655 if ( !gme ) 18656 { 18657 PRINT_ERROR("Performing IMPRINT with entities containing geometry from\n" 18658 "different modeling engines is not allowed.\n" ); 18659 return CUBIT_FAILURE; 18660 } 18661 18662 if( CubitUndo::get_undo_enabled() ) 18663 CubitUndo::save_state_with_cubit_file( ref_faces ); 18664 18665 //do the imprint onto face1 18666 DLIList<BodySM*> new_bodysm_list; 18667 CubitStatus status = gme->tolerant_imprint(surf_list, new_bodysm_list); 18668 18669 //if we failed...get out 18670 if( status == CUBIT_FAILURE ) 18671 { 18672 if( CubitUndo::get_undo_enabled() ) 18673 CubitUndo::remove_last_undo(); 18674 18675 return CUBIT_FAILURE; 18676 } 18677 18678 DLIList<Body*> result_bodies; 18679 DLIList<Body*> original_body_list; 18680 original_body_list.append(body1); 18681 original_body_list.append(body2); 18682 status = finish_sm_op( original_body_list, new_bodysm_list, result_bodies ); 18683 18684 18685 if( merge ) 18686 { 18687 DLIList<RefFace*> faces_to_merge, tmp_faces; 18688 body1->ref_faces(faces_to_merge); 18689 body2->ref_faces(tmp_faces); 18690 faces_to_merge += tmp_faces; 18691 faces_to_merge -= faces_not_to_merge; 18692 if(faces_to_merge.size() > 1) 18693 { 18694 MergeTool::instance()->merge_reffaces(faces_to_merge); 18695 } 18696 } 18697 } 18698 18699 return CUBIT_SUCCESS; 18700 } 18701 18702 18703 CubitStatus GeometryModifyTool::tolerant_imprint( RefFace *ref_face, 18704 DLIList<RefEdge*> &ref_edge_list, 18705 Body *&new_body, 18706 bool merge ) 18707 { 18708 int i; 18709 DLIList<Body*> bodies_to_merge; 18710 DLIList<Body*> blank_bodies; 18711 18712 DLIList<RefEdge*> tmp_edges; 18713 ref_face->ref_edges( tmp_edges ); 18714 18715 for( i=tmp_edges.size(); i--; ) 18716 { 18717 RefEdge *tmp_edge = tmp_edges.get_and_step(); 18718 DLIList<Body*> body_list; 18719 tmp_edge->bodies( body_list ); 18720 blank_bodies += body_list; 18721 } 18722 18723 if( merge ) 18724 { 18725 bodies_to_merge += blank_bodies; 18726 18727 for( i=ref_edge_list.size(); i--; ) 18728 { 18729 RefEdge *tmp_edge = ref_edge_list.get_and_step(); 18730 DLIList<Body*> body_list; 18731 tmp_edge->bodies( body_list ); 18732 bodies_to_merge += body_list; 18733 } 18734 18735 bodies_to_merge.uniquify_ordered(); 18736 } 18737 18738 DLIList<Body*> original_body_list; 18739 ref_face->bodies( original_body_list ); 18740 18741 DLIList<Surface*> surf_list( 1 ); 18742 DLIList<Curve*> curve_list(ref_edge_list.size()); 18743 DLIList<RefFace*> ref_face_list( 1 ); 18744 ref_face_list.append( ref_face ); 18745 18746 //prohibit imprinting on partition bodies 18747 for( int k=0; k<blank_bodies.size(); k++ ) 18748 { 18749 if( NULL == get_engine( blank_bodies[k]->bridge_manager()->topology_bridge() ) ) 18750 { 18751 PRINT_ERROR("Performing IMPRINT on entities with partitions\n" 18752 " is not allowed.\n" ); 18753 return CUBIT_FAILURE; 18754 } 18755 } 18756 18757 GeometryModifyEngine* gme = common_modify_engine( ref_face_list, 18758 ref_edge_list, 18759 surf_list, 18760 curve_list, 18761 true); 18762 if ( !gme ) 18763 { 18764 PRINT_ERROR("Performing IMPRINT with entities containing geometry from\n" 18765 "different modeling engines is not allowed.\n" ); 18766 return CUBIT_FAILURE; 18767 } 18768 18769 18770 if( CubitUndo::get_undo_enabled() ) 18771 { 18772 DLIList<RefFace*> ref_faces(1); 18773 ref_faces.append( ref_face ); 18774 CubitUndo::save_state_with_cubit_file( ref_faces ); 18775 } 18776 18777 DLIList<BodySM*> body_sm_list; 18778 for(i=original_body_list.size(); i--;) 18779 body_sm_list.append(original_body_list.get_and_step()->get_body_sm_ptr()); 18780 18781 int process_composites = 0; 18782 if(contains_composites(original_body_list)) 18783 process_composites = 1; 18784 18785 DLIList<TopologyBridge*> tb_list; 18786 if(process_composites) 18787 { 18788 // Turn certain attributes on. 18789 do_attribute_setup(); 18790 // Push virtual attributes down to solid model topology before 18791 // doing the imprint. 18792 push_attributes_before_modify(body_sm_list); 18793 DLIList<TopologyBridge*> tmp_tb_list; 18794 CAST_LIST(surf_list, tmp_tb_list, TopologyBridge); 18795 // Put "ORIGINAL" attributes on the bodies being imprinted and 18796 // the curves as these originally existed. 18797 push_named_attributes_to_curves_and_points(tmp_tb_list, "ORIGINAL"); 18798 CAST_LIST(curve_list, tb_list, TopologyBridge); 18799 push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL"); 18800 push_named_attributes_to_curves_and_points(tb_list, "IMPRINTER"); 18801 } 18802 18803 CubitStatus status = CUBIT_FAILURE; 18804 DLIList<BodySM*> new_body_list; 18805 // The bridges doing the imprinting often get split during the process but 18806 // because of the way we are making copies, the IMPRINTER attribute doesn't 18807 // get propagated to them. temporary_bridges will be filled in with any 18808 // additional IMPRINTER bridges we need to consider below when deciding whether to 18809 // keep composite attributes. 18810 DLIList<TopologyBridge*> temporary_bridges; 18811 for(i=surf_list.size(); i>0; i--) 18812 { 18813 Surface *cur_surf = surf_list.get_and_step(); 18814 BodySM *new_body_sm = NULL; 18815 CubitStatus tmp_status = gme->tolerant_imprint_surface_with_curves( 18816 cur_surf, curve_list, 18817 temporary_bridges, 18818 new_body_sm); 18819 if(new_body_sm) 18820 new_body_list.append(new_body_sm); 18821 if(tmp_status == CUBIT_SUCCESS) 18822 status = tmp_status; 18823 } 18824 18825 temporary_bridges.uniquify_ordered(); 18826 18827 if( status == CUBIT_FAILURE ) 18828 { 18829 if( CubitUndo::get_undo_enabled() ) 18830 CubitUndo::remove_last_undo(); 18831 18832 if(process_composites) 18833 { 18834 remove_pushed_attributes(new_body_list, original_body_list); 18835 do_attribute_cleanup(); 18836 } 18837 18838 while(temporary_bridges.size()) 18839 { 18840 TopologyBridge* bridge = temporary_bridges.pop(); 18841 bridge->get_geometry_query_engine()->delete_topology_bridge(bridge); 18842 } 18843 18844 return CUBIT_FAILURE; 18845 } 18846 else 18847 { 18848 if(process_composites) 18849 { 18850 // Analyze the results and adjust virtual attributes as necessary. 18851 DLIList<TopologyBridge*> tmp_tb_list; 18852 CAST_LIST(new_body_list, tmp_tb_list, TopologyBridge); 18853 tb_list.merge_unique(tmp_tb_list); 18854 // The bridges coming back in temporary_bridges may not have IMPRINTER 18855 // attributes on them becuase of the way they were generated below. Make 18856 // sure they get IMPRINTER attributes. 18857 push_named_attributes_to_curves_and_points(temporary_bridges, "IMPRINTER"); 18858 tb_list += temporary_bridges; 18859 GeometryQueryTool::instance()->ige_attribute_after_imprinting(tb_list, original_body_list); 18860 18861 18862 // Clean up attributes. 18863 remove_imprint_attributes_after_modify(body_sm_list, new_body_list); 18864 18865 // Restore the virtual geometry. 18866 restore_vg_after_modify(new_body_list, original_body_list, gme); 18867 remove_pushed_attributes(new_body_list, original_body_list); 18868 } 18869 } 18870 // cleanup temp bridges 18871 while(temporary_bridges.size()) 18872 { 18873 TopologyBridge* bridge = temporary_bridges.pop(); 18874 bridge->get_geometry_query_engine()->delete_topology_bridge(bridge); 18875 } 18876 18877 DLIList<Body*> result_bodies; 18878 status = finish_sm_op( original_body_list, new_body_list, result_bodies ); 18879 18880 if(process_composites) 18881 do_attribute_cleanup(); 18882 18883 if( status == CUBIT_FAILURE ) 18884 { 18885 if( CubitUndo::get_undo_enabled() ) 18886 CubitUndo::remove_last_undo(); 18887 return CUBIT_FAILURE; 18888 } 18889 18890 if( merge ) 18891 MergeTool::instance()->merge_bodies( bodies_to_merge ); 18892 18893 if( result_bodies.size() == 1 ) 18894 new_body = result_bodies.get(); 18895 else 18896 return CUBIT_FAILURE; 18897 18898 return status; 18899 } 18900 18901 CubitStatus GeometryModifyTool::unmerge_and_return_merge_partners(RefEdge *input_curve, 18902 DLIList<DLIList<RefEdge*>*> &curve_merge_lists, 18903 DLIList<DLIList<RefFace*>*> &surf_merge_lists) 18904 { 18905 if(!input_curve->is_merged()) 18906 return CUBIT_FAILURE; 18907 18908 DLIList<RefFace*> vert_surfs; 18909 input_curve->start_vertex()->ref_faces(vert_surfs); 18910 input_curve->end_vertex()->ref_faces(vert_surfs); 18911 vert_surfs.uniquify_unordered(); 18912 for(int i=vert_surfs.size(); i>0; i--) 18913 { 18914 RefFace *cur_surf = vert_surfs.get_and_step(); 18915 if(cur_surf->is_merged()) 18916 { 18917 DLIList<RefVolume*> surf_vols; 18918 DLIList<RefFace*> all_surfs_on_both_vols; 18919 cur_surf->ref_volumes(surf_vols); 18920 for(int j=surf_vols.size(); j>0; j--) 18921 { 18922 RefVolume *cur_vol = surf_vols.get_and_step(); 18923 cur_vol->ref_faces(all_surfs_on_both_vols); 18924 } 18925 all_surfs_on_both_vols.uniquify_unordered(); 18926 DLIList<RefFace*> all_surfs_on_both_vols_after_unmerge; 18927 OldUnmergeCode::instance().unmerge(cur_surf, false); 18928 for(int j=surf_vols.size(); j>0; j--) 18929 { 18930 RefVolume *cur_vol = surf_vols.get_and_step(); 18931 cur_vol->ref_faces(all_surfs_on_both_vols_after_unmerge); 18932 } 18933 all_surfs_on_both_vols_after_unmerge.uniquify_unordered(); 18934 all_surfs_on_both_vols_after_unmerge -= all_surfs_on_both_vols; 18935 if(all_surfs_on_both_vols_after_unmerge.size() != 1) 18936 return CUBIT_FAILURE; 18937 all_surfs_on_both_vols_after_unmerge.append(cur_surf); 18938 DLIList<RefFace*> *new_list = new DLIList<RefFace*>(); 18939 for(int r=all_surfs_on_both_vols_after_unmerge.size(); r>0; r--) 18940 { 18941 RefFace *cur_surf = all_surfs_on_both_vols_after_unmerge.get_and_step(); 18942 new_list->append(cur_surf); 18943 } 18944 surf_merge_lists.append(new_list); 18945 } 18946 } 18947 DLIList<RefEdge*> vert_curves; 18948 input_curve->start_vertex()->ref_edges(vert_curves); 18949 input_curve->end_vertex()->ref_edges(vert_curves); 18950 vert_curves.uniquify_unordered(); 18951 for(int i=vert_curves.size(); i>0; i--) 18952 { 18953 RefEdge *cur_curve = vert_curves.get_and_step(); 18954 if(cur_curve->is_merged()) 18955 { 18956 DLIList<RefFace*> curve_surfs; 18957 DLIList<RefEdge*> all_curves_on_all_surfs; 18958 cur_curve->ref_faces(curve_surfs); 18959 for(int j=curve_surfs.size(); j>0; j--) 18960 { 18961 RefFace *cur_surf = curve_surfs.get_and_step(); 18962 cur_surf->ref_edges(all_curves_on_all_surfs); 18963 } 18964 all_curves_on_all_surfs.uniquify_unordered(); 18965 DLIList<RefEdge*> all_curves_on_all_surfs_after_unmerge; 18966 OldUnmergeCode::instance().unmerge(cur_curve, true); 18967 for(int j=curve_surfs.size(); j>0; j--) 18968 { 18969 RefFace *cur_surf = curve_surfs.get_and_step(); 18970 cur_surf->ref_edges(all_curves_on_all_surfs_after_unmerge); 18971 } 18972 all_curves_on_all_surfs_after_unmerge.uniquify_unordered(); 18973 all_curves_on_all_surfs_after_unmerge -= all_curves_on_all_surfs; 18974 if(all_curves_on_all_surfs_after_unmerge.size() < 1) 18975 return CUBIT_FAILURE; 18976 all_curves_on_all_surfs_after_unmerge.append_unique(cur_curve); 18977 DLIList<RefEdge*> *new_list = new DLIList<RefEdge*>(); 18978 for(int r=all_curves_on_all_surfs_after_unmerge.size(); r>0; r--) 18979 { 18980 RefEdge *cur_edge = all_curves_on_all_surfs_after_unmerge.get_and_step(); 18981 new_list->append(cur_edge); 18982 } 18983 curve_merge_lists.append(new_list); 18984 } 18985 } 18986 return CUBIT_SUCCESS; 18987 } 18988 18989 CubitStatus GeometryModifyTool::unmerge_and_return_merge_partners(RefVertex *input_vertex, 18990 DLIList<DLIList<RefVertex*>*> &vert_merge_lists, 18991 DLIList<DLIList<RefEdge*>*> &curve_merge_lists, 18992 DLIList<DLIList<RefFace*>*> &surf_merge_lists) 18993 { 18994 if(!input_vertex->is_merged()) 18995 return CUBIT_FAILURE; 18996 18997 DLIList<RefFace*> vert_surfs; 18998 input_vertex->ref_faces(vert_surfs); 18999 for(int i=vert_surfs.size(); i>0; i--) 19000 { 19001 RefFace *cur_surf = vert_surfs.get_and_step(); 19002 if(cur_surf->is_merged()) 19003 { 19004 DLIList<RefVolume*> surf_vols; 19005 DLIList<RefFace*> all_surfs_on_both_vols; 19006 cur_surf->ref_volumes(surf_vols); 19007 for(int j=surf_vols.size(); j>0; j--) 19008 { 19009 RefVolume *cur_vol = surf_vols.get_and_step(); 19010 cur_vol->ref_faces(all_surfs_on_both_vols); 19011 } 19012 all_surfs_on_both_vols.uniquify_unordered(); 19013 DLIList<RefFace*> all_surfs_on_both_vols_after_unmerge; 19014 OldUnmergeCode::instance().unmerge(cur_surf, false); 19015 for(int j=surf_vols.size(); j>0; j--) 19016 { 19017 RefVolume *cur_vol = surf_vols.get_and_step(); 19018 cur_vol->ref_faces(all_surfs_on_both_vols_after_unmerge); 19019 } 19020 all_surfs_on_both_vols_after_unmerge.uniquify_unordered(); 19021 all_surfs_on_both_vols_after_unmerge -= all_surfs_on_both_vols; 19022 if(all_surfs_on_both_vols_after_unmerge.size() != 1) 19023 return CUBIT_FAILURE; 19024 all_surfs_on_both_vols_after_unmerge.append(cur_surf); 19025 DLIList<RefFace*> *new_list = new DLIList<RefFace*>(); 19026 for(int r=all_surfs_on_both_vols_after_unmerge.size(); r>0; r--) 19027 { 19028 RefFace *cur_surf = all_surfs_on_both_vols_after_unmerge.get_and_step(); 19029 new_list->append(cur_surf); 19030 } 19031 surf_merge_lists.append(new_list); 19032 } 19033 } 19034 DLIList<RefEdge*> vert_curves; 19035 input_vertex->ref_edges(vert_curves); 19036 for(int i=vert_curves.size(); i>0; i--) 19037 { 19038 RefEdge *cur_curve = vert_curves.get_and_step(); 19039 if(cur_curve->is_merged()) 19040 { 19041 DLIList<RefFace*> curve_surfs; 19042 DLIList<RefEdge*> all_curves_on_all_surfs; 19043 cur_curve->ref_faces(curve_surfs); 19044 for(int j=curve_surfs.size(); j>0; j--) 19045 { 19046 RefFace *cur_surf = curve_surfs.get_and_step(); 19047 cur_surf->ref_edges(all_curves_on_all_surfs); 19048 } 19049 all_curves_on_all_surfs.uniquify_unordered(); 19050 DLIList<RefEdge*> all_curves_on_all_surfs_after_unmerge; 19051 OldUnmergeCode::instance().unmerge(cur_curve, false); 19052 for(int j=curve_surfs.size(); j>0; j--) 19053 { 19054 RefFace *cur_surf = curve_surfs.get_and_step(); 19055 cur_surf->ref_edges(all_curves_on_all_surfs_after_unmerge); 19056 } 19057 all_curves_on_all_surfs_after_unmerge.uniquify_unordered(); 19058 all_curves_on_all_surfs_after_unmerge -= all_curves_on_all_surfs; 19059 if(all_curves_on_all_surfs_after_unmerge.size() < 1) 19060 return CUBIT_FAILURE; 19061 all_curves_on_all_surfs_after_unmerge.append_unique(cur_curve); 19062 DLIList<RefEdge*> *new_list = new DLIList<RefEdge*>(); 19063 for(int r=all_curves_on_all_surfs_after_unmerge.size(); r>0; r--) 19064 { 19065 RefEdge *cur_edge = all_curves_on_all_surfs_after_unmerge.get_and_step(); 19066 new_list->append(cur_edge); 19067 } 19068 curve_merge_lists.append(new_list); 19069 } 19070 } 19071 vert_curves.clean_out(); 19072 input_vertex->ref_edges(vert_curves); 19073 DLIList<RefVertex*> curve_verts; 19074 for(int i=vert_curves.size(); i>0; i--) 19075 { 19076 RefEdge *cur_curve = vert_curves.get_and_step(); 19077 cur_curve->ref_vertices(curve_verts); 19078 } 19079 curve_verts.uniquify_unordered(); 19080 DLIList<RefVertex*> verts_after_unmerge; 19081 OldUnmergeCode::instance().unmerge(input_vertex); 19082 for(int j=vert_curves.size(); j>0; j--) 19083 { 19084 RefEdge *cur_curve = vert_curves.get_and_step(); 19085 cur_curve->ref_vertices(verts_after_unmerge); 19086 } 19087 verts_after_unmerge.uniquify_unordered(); 19088 verts_after_unmerge -= curve_verts; 19089 if(verts_after_unmerge.size() < 1) 19090 return CUBIT_FAILURE; 19091 verts_after_unmerge.append_unique(input_vertex); 19092 DLIList<RefVertex*> *new_list = new DLIList<RefVertex*>(); 19093 for(int r=verts_after_unmerge.size(); r>0; r--) 19094 { 19095 RefVertex *cur_vert = verts_after_unmerge.get_and_step(); 19096 new_list->append(cur_vert); 19097 } 19098 vert_merge_lists.append(new_list); 19099 19100 return CUBIT_SUCCESS; 19101 } 19102 19103 CubitStatus GeometryModifyTool::unmerge_input(RefEdge *curve1, 19104 RefEdge *curve2, 19105 DLIList<DLIList<RefEdge*>*> &curve_merge_lists, 19106 DLIList<DLIList<RefFace*>*> &surf_merge_lists) 19107 { 19108 if(curve1->is_merged()) 19109 { 19110 this->unmerge_and_return_merge_partners(curve1, curve_merge_lists, surf_merge_lists); 19111 } 19112 if(curve2->is_merged()) 19113 { 19114 this->unmerge_and_return_merge_partners(curve2, curve_merge_lists, surf_merge_lists); 19115 } 19116 return CUBIT_SUCCESS; 19117 } 19118 19119 CubitStatus GeometryModifyTool::find_best_curves_to_merge(DLIList<RefEdge*> *&curves_from_curve1, 19120 DLIList<RefEdge*> *&curves_from_curve2, 19121 RefEdge *&curve1, 19122 RefEdge *&curve2) 19123 { 19124 /* 19125 for(int i=curves_from_curve1.size(); i>0; i--) 19126 { 19127 if found better curve than curve1 set curve1 to be this curve 19128 } 19129 for(int i=curves_from_curve2.size(); i>0; i--) 19130 { 19131 if found better curve than curve2 set curve2 to be this curve 19132 } 19133 */ 19134 return CUBIT_SUCCESS; 19135 } 19136 19137 CubitStatus GeometryModifyTool::imprint_and_merge_curves(RefEdge *input_curve1, 19138 RefEdge *input_curve2, 19139 DLIList<RefVertex*> &vert_list, 19140 double divergence_angle, 19141 DLIList<DLIList<RefEdge*>*> &curves_to_merge1, 19142 DLIList<DLIList<RefEdge*>*> &curves_to_merge2, 19143 DLIList<DLIList<RefEdge*>*> &prev_curve_merge_lists, 19144 DLIList<DLIList<RefFace*>*> &prev_surf_merge_lists) 19145 { 19146 CubitStatus status; 19147 status = this->unmerge_input(input_curve1, input_curve2, prev_curve_merge_lists, prev_surf_merge_lists); 19148 if(status == CUBIT_FAILURE) 19149 return status; 19150 RefEdge *curve1, *curve2; 19151 DLIList<RefEdge*> *curves_from_curve1 = new DLIList<RefEdge*>(); 19152 DLIList<RefEdge*> *curves_from_curve2 = new DLIList<RefEdge*>(); 19153 for(int i=prev_curve_merge_lists.size(); i>0; i--) 19154 { 19155 DLIList<RefEdge*> *cur_list = prev_curve_merge_lists.get_and_step(); 19156 // DLIList<RefEdge*> cur_list = prev_curve_merge_lists.get(); 19157 if(cur_list->move_to(input_curve1)) 19158 { 19159 *curves_from_curve1 = *cur_list; 19160 // prev_curve_merge_lists.remove(); 19161 } 19162 else if(cur_list->move_to(input_curve2)) 19163 { 19164 *curves_from_curve2 = *cur_list; 19165 // prev_curve_merge_lists.remove(); 19166 } 19167 // else 19168 // prev_curve_merge_lists.step(); 19169 } 19170 // Make sure at least the input curves are in the lists. 19171 if(curves_from_curve1->size() == 0) 19172 curves_from_curve1->append(input_curve1); 19173 if(curves_from_curve2->size() == 0) 19174 curves_from_curve2->append(input_curve2); 19175 19176 curve1 = input_curve1; 19177 curve2 = input_curve2; 19178 status = this->find_best_curves_to_merge(curves_from_curve1, curves_from_curve2, curve1, curve2); 19179 if(CUBIT_FAILURE == status) 19180 return status; 19181 19182 DLIList<CubitVector> merge_end_points_on_curve1, merge_end_points_on_curve2; 19183 DLIList<CubitBoolean> split_flags1, split_flags2; 19184 this->calculate_split_points_for_merge(curve1, curve2, vert_list, NULL, 19185 merge_end_points_on_curve1, merge_end_points_on_curve2, split_flags1, split_flags2, divergence_angle); 19186 19187 merge_end_points_on_curve1.reset(); 19188 split_flags1.reset(); 19189 for(int k=merge_end_points_on_curve1.size(); k>0; k=k-2) 19190 { 19191 CubitVector end_point1 = merge_end_points_on_curve1.get_and_step(); 19192 CubitVector end_point2 = merge_end_points_on_curve1.get_and_step(); 19193 bool split_flag_end = split_flags1.get_and_step(); 19194 if(split_flag_end) 19195 { 19196 DLIList<RefEdge*> *cur_merge_list = new DLIList<RefEdge*>(); 19197 for(int n=curves_from_curve1->size(); n>0; n--) 19198 { 19199 RefEdge *curve_to_split = curves_from_curve1->get(); 19200 CubitVector mid = (end_point1 + end_point2)/2.0; 19201 CubitVector pos_for_identifying; 19202 curve_to_split->closest_point_trimmed(mid, pos_for_identifying); 19203 19204 DLIList<CubitVector> loc_list; 19205 loc_list.append(end_point2); 19206 CubitStatus loc_status; 19207 19208 int expected_edge_id_1 = RefEntityFactory::instance()->current_edge_id() + 1; 19209 int expected_edge_id_2 = expected_edge_id_1 + 1; 19210 19211 if(curve_to_split->body()) 19212 { 19213 DLIList<Body*> edge_bodies, new_bodies; 19214 edge_bodies.append(curve_to_split->body()); // for now just handle single body case 19215 19216 loc_status = this->imprint( edge_bodies, loc_list, new_bodies ); 19217 } 19218 else 19219 { 19220 DLIList<RefEdge*> new_ref_edges; 19221 loc_status = this->split_free_curve( curve_to_split, loc_list, new_ref_edges ); 19222 } 19223 19224 if(loc_status == CUBIT_FAILURE) 19225 { 19226 return CUBIT_FAILURE; 19227 } 19228 19229 RefEdge *new_edge_1 = RefEntityFactory::instance()->get_ref_edge(expected_edge_id_1); 19230 RefEdge *new_edge_2 = RefEntityFactory::instance()->get_ref_edge(expected_edge_id_2); 19231 19232 if(!new_edge_1 || !new_edge_2) 19233 { 19234 return CUBIT_FAILURE; 19235 } 19236 19237 CubitVector closest; 19238 new_edge_1->closest_point_trimmed(pos_for_identifying, closest); 19239 if(closest.about_equal(pos_for_identifying)) 19240 { 19241 cur_merge_list->append(new_edge_1); 19242 RefEdge *edge_that_was_split = curves_from_curve1->get(); 19243 curves_from_curve1->change_to(new_edge_2); 19244 for(int w=prev_curve_merge_lists.size(); w>0; w--) 19245 { 19246 DLIList<RefEdge*> *cur_list = prev_curve_merge_lists.get_and_step(); 19247 if(cur_list->move_to(edge_that_was_split)) 19248 { 19249 cur_list->change_to(new_edge_2); 19250 w=0; 19251 } 19252 } 19253 } 19254 else 19255 { 19256 cur_merge_list->append(new_edge_2); 19257 RefEdge *edge_that_was_split = curves_from_curve1->get(); 19258 curves_from_curve1->change_to(new_edge_1); 19259 for(int w=prev_curve_merge_lists.size(); w>0; w--) 19260 { 19261 DLIList<RefEdge*> *cur_list = prev_curve_merge_lists.get_and_step(); 19262 if(cur_list->move_to(edge_that_was_split)) 19263 { 19264 cur_list->change_to(new_edge_1); 19265 w=0; 19266 } 19267 } 19268 } 19269 curves_from_curve1->step(); 19270 } 19271 curves_to_merge1.append(cur_merge_list); 19272 } 19273 else 19274 { 19275 curves_to_merge1.append(curves_from_curve1); 19276 } 19277 } 19278 19279 merge_end_points_on_curve2.reset(); 19280 split_flags2.reset(); 19281 for(int k=merge_end_points_on_curve2.size(); k>0; k=k-2) 19282 { 19283 CubitVector end_point1 = merge_end_points_on_curve2.get_and_step(); 19284 CubitVector end_point2 = merge_end_points_on_curve2.get_and_step(); 19285 bool split_flag_end = split_flags2.get_and_step(); 19286 if(split_flag_end) 19287 { 19288 DLIList<RefEdge*> *cur_merge_list = new DLIList<RefEdge*>(); 19289 for(int n=curves_from_curve2->size(); n>0; n--) 19290 { 19291 RefEdge *curve_to_split = curves_from_curve2->get(); 19292 CubitVector mid = (end_point1 + end_point2)/2.0; 19293 CubitVector pos_for_identifying; 19294 curve_to_split->closest_point_trimmed(mid, pos_for_identifying); 19295 19296 DLIList<CubitVector> loc_list; 19297 loc_list.append(end_point2); 19298 CubitStatus loc_status; 19299 19300 int expected_edge_id_1 = RefEntityFactory::instance()->current_edge_id() + 1; 19301 int expected_edge_id_2 = expected_edge_id_1 + 1; 19302 19303 if(curve_to_split->body()) 19304 { 19305 DLIList<Body*> edge_bodies, new_bodies; 19306 edge_bodies.append(curve_to_split->body()); // for now just handle single body case 19307 19308 loc_status = this->imprint( edge_bodies, loc_list, new_bodies ); 19309 } 19310 else 19311 { 19312 DLIList<RefEdge*> new_ref_edges; 19313 loc_status = this->split_free_curve( curve_to_split, loc_list, new_ref_edges ); 19314 } 19315 19316 if(loc_status == CUBIT_FAILURE) 19317 { 19318 return CUBIT_FAILURE; 19319 } 19320 19321 RefEdge *new_edge_1 = RefEntityFactory::instance()->get_ref_edge(expected_edge_id_1); 19322 RefEdge *new_edge_2 = RefEntityFactory::instance()->get_ref_edge(expected_edge_id_2); 19323 19324 if(!new_edge_1 || !new_edge_2) 19325 { 19326 return CUBIT_FAILURE; 19327 } 19328 19329 CubitVector closest; 19330 new_edge_1->closest_point_trimmed(pos_for_identifying, closest); 19331 if(closest.about_equal(pos_for_identifying)) 19332 { 19333 cur_merge_list->append(new_edge_1); 19334 RefEdge *edge_that_was_split = curves_from_curve2->get(); 19335 curves_from_curve2->change_to(new_edge_2); 19336 for(int w=prev_curve_merge_lists.size(); w>0; w--) 19337 { 19338 DLIList<RefEdge*> *cur_list = prev_curve_merge_lists.get_and_step(); 19339 if(cur_list->move_to(edge_that_was_split)) 19340 { 19341 cur_list->change_to(new_edge_2); 19342 w=0; 19343 } 19344 } 19345 } 19346 else 19347 { 19348 cur_merge_list->append(new_edge_2); 19349 RefEdge *edge_that_was_split = curves_from_curve2->get(); 19350 curves_from_curve2->change_to(new_edge_1); 19351 for(int w=prev_curve_merge_lists.size(); w>0; w--) 19352 { 19353 DLIList<RefEdge*> *cur_list = prev_curve_merge_lists.get_and_step(); 19354 if(cur_list->move_to(edge_that_was_split)) 19355 { 19356 cur_list->change_to(new_edge_1); 19357 w=0; 19358 } 19359 } 19360 } 19361 curves_from_curve2->step(); 19362 } 19363 curves_to_merge2.append(cur_merge_list); 19364 } 19365 else 19366 { 19367 curves_to_merge2.append(curves_from_curve2); 19368 } 19369 } 19370 return status; 19371 } 19372 19373 19374 CubitStatus GeometryModifyTool::find_overlap_region(RefEdge *c1, 19375 RefEdge *c2, 19376 RefVertex *v1, 19377 RefVertex *v2, 19378 bool forward_c1, 19379 bool forward_c2, 19380 bool &full_c1, 19381 bool &full_c2, 19382 double &c1_stop_param, 19383 double &c2_stop_param, 19384 double divergence_angle) 19385 { 19386 CubitStatus status = CUBIT_SUCCESS; 19387 double start_t, end_t, dt, cur_t; 19388 int num_segments = 20; 19389 double reverse_multiplier; 19390 double divergence_tol = cos(divergence_angle*CUBIT_PI/180.0); 19391 int i; 19392 19393 if(forward_c1 != forward_c2) 19394 reverse_multiplier = -1.0; 19395 else 19396 reverse_multiplier = 1.0; 19397 19398 // Start from the projection of v2 onto c1. 19399 CubitVector tmp_pos; 19400 c1->closest_point_trimmed(v2->coordinates(), tmp_pos); 19401 start_t = c1->u_from_position(tmp_pos); 19402 if(forward_c1) 19403 { 19404 end_t = c1->end_param(); 19405 dt = (end_t-start_t)/(double)num_segments; 19406 cur_t = start_t + dt; 19407 } 19408 else 19409 { 19410 end_t = c1->start_param(); 19411 dt = (end_t-start_t)/(double)num_segments; 19412 cur_t = start_t + dt; 19413 } 19414 // Check all of the interior points to see if the tangents 19415 // of the two curves are within tolerance. 19416 bool went_past_end_of_c2 = false; 19417 bool went_out_of_angle_tolerance = false; 19418 for(i=num_segments; i>0; i--) 19419 // for(i=num_segments-1; i>0; i--) 19420 { 19421 if(i==1) 19422 { 19423 cur_t = end_t; 19424 } 19425 // Evaluate curve 1. 19426 CubitVector vec1, vec2, tangent1, tangent2; 19427 c1->position_from_u(cur_t, vec1); 19428 c1->tangent(vec1, tangent1); 19429 tangent1.normalize(); 19430 // Project the point to curve 2 and get the tangent. 19431 c2->closest_point_trimmed(vec1, vec2); 19432 c2->tangent(vec2, tangent2); 19433 tangent2.normalize(); 19434 if(((tangent1 % tangent2) * reverse_multiplier) > divergence_tol) 19435 { 19436 CubitVector check_vec = vec2-vec1; 19437 double dot_val = 0.0; 19438 if(check_vec.length() > 1e-6) 19439 { 19440 check_vec.normalize(); 19441 dot_val = check_vec % tangent2; 19442 } 19443 if(dot_val > .001 || dot_val < -.001) 19444 { 19445 went_past_end_of_c2 = true; 19446 } 19447 else 19448 { 19449 // If we made it to the end of curve 1 check to see 19450 // if the end of curve 2 is within some tolerance of 19451 // the endpoint of curve 1 and if so set the 19452 // full_c2 flag to true. 19453 if(i==1) 19454 { 19455 RefVertex *c1_end, *c2_end; 19456 if(forward_c1) 19457 c1_end = c1->end_vertex(); 19458 else 19459 c1_end = c1->start_vertex(); 19460 if(forward_c2) 19461 c2_end = c2->end_vertex(); 19462 else 19463 c2_end = c2->start_vertex(); 19464 if(c1_end == c2_end) // verts are already merged 19465 full_c2 = true; 19466 else 19467 { 19468 CubitVector c2_end_pos; 19469 if(forward_c2) 19470 c2_end_pos = c2->end_coordinates(); 19471 else 19472 c2_end_pos = c2->start_coordinates(); 19473 double dist_sq_1 = (vec1-vec2).length_squared(); 19474 double dist_sq_2 = (vec1-c2_end_pos).length_squared(); 19475 if(dist_sq_2 < 2.25*dist_sq_1) 19476 full_c2 = true; 19477 } 19478 } 19479 } 19480 } 19481 else 19482 { 19483 went_out_of_angle_tolerance = true; 19484 } 19485 if(went_past_end_of_c2) 19486 { 19487 i=0; 19488 full_c2 = true; 19489 c1_stop_param = cur_t; 19490 // calculate split point on curve 1 19491 } 19492 else if(went_out_of_angle_tolerance) 19493 { 19494 if(i==num_segments) 19495 status = CUBIT_FAILURE; 19496 i=0; 19497 c1_stop_param = cur_t; 19498 c2_stop_param = c2->u_from_position(vec2); 19499 } 19500 19501 cur_t += dt; 19502 } 19503 19504 if(i==0) 19505 { 19506 full_c1 = true; 19507 } 19508 19509 return status; 19510 } 19511 19512 CubitStatus GeometryModifyTool::match_v1_to_c1(RefVertex *&v1, 19513 RefVertex *&v2, 19514 RefVertex *c1_v1, 19515 RefVertex *c1_v2, 19516 RefVertex *c2_v1, 19517 RefVertex *c2_v2) 19518 { 19519 CubitStatus status = CUBIT_SUCCESS; 19520 19521 if(v1 == c1_v1 || v1 == c1_v2) 19522 { 19523 if(v2 == c2_v1 || v2 == c2_v2) 19524 { 19525 // everything is fine 19526 } 19527 else 19528 status = CUBIT_FAILURE; 19529 } 19530 else if(v1 == c2_v1 || v1 == c2_v2) 19531 { 19532 if(v2 == c1_v1 || v2 == c1_v2) 19533 { 19534 RefVertex *tmp = v1; 19535 v1 = v2; 19536 v2 = tmp; 19537 } 19538 else 19539 status = CUBIT_FAILURE; 19540 } 19541 else 19542 status = CUBIT_FAILURE; 19543 19544 return status; 19545 } 19546 19547 CubitStatus GeometryModifyTool::calculate_split_points_for_merge(RefEdge* c1, 19548 RefEdge* c2, 19549 DLIList<RefVertex*> &verts_to_merge, 19550 double *merge_tolerance, 19551 DLIList<CubitVector> &merge_end_points_on_curve1, 19552 DLIList<CubitVector> &merge_end_points_on_curve2, 19553 DLIList<CubitBoolean> &split_flags_for_curve1, 19554 DLIList<CubitBoolean> &split_flags_for_curve2, 19555 double divergence_angle) 19556 { 19557 19558 CubitStatus status = CUBIT_SUCCESS; 19559 bool all_done = false; 19560 19561 // Get the vertices of the two curves. 19562 RefVertex *c1_v1 = c1->start_vertex(); 19563 RefVertex *c1_v2 = c1->end_vertex(); 19564 RefVertex *c2_v1 = c2->start_vertex(); 19565 RefVertex *c2_v2 = c2->end_vertex(); 19566 19567 // Check for closed curves. 19568 bool c1_closed = false; 19569 if(c1_v1 == c1_v2) 19570 c1_closed = true; 19571 bool merge_verts_at_both_ends = false; 19572 19573 // If we are told that certain vertices need to merge 19574 // we will know that we do not need to split the curves there. 19575 bool full_c1=false, full_c2=false; 19576 int verts_to_merge_size = verts_to_merge.size(); 19577 RefVertex *v1, *v2; 19578 if(verts_to_merge_size > 0) 19579 { 19580 // Verts to merge should always come in pairs. 19581 if(verts_to_merge_size % 2 != 0) 19582 { 19583 status = CUBIT_FAILURE; 19584 } 19585 else 19586 { 19587 if(verts_to_merge_size > 2 || c1_closed) 19588 merge_verts_at_both_ends = true; 19589 19590 verts_to_merge.reset(); 19591 // Process the first set of verts to merge. 19592 v1 = verts_to_merge.get_and_step(); 19593 v2 = verts_to_merge.get_and_step(); 19594 // Make sure v1 corresponds to c1 and v2 to c2. 19595 status = match_v1_to_c1(v1, v2, c1_v1, c1_v2, c2_v1, c2_v2); 19596 } 19597 if(status == CUBIT_SUCCESS) 19598 { 19599 // Determine whether the verts are at the 19600 // beginning or end of curves. 19601 bool forward_c1, forward_c2; 19602 if(v1 == c1_v1) 19603 forward_c1 = true; 19604 else 19605 forward_c1 = false; 19606 if(v2 == c2_v1) 19607 forward_c2 = true; 19608 else 19609 forward_c2 = false; 19610 19611 double c1_stop_param, c2_stop_param; 19612 19613 status = find_overlap_region(c1, c2, v1, v2, forward_c1, forward_c2, full_c1, full_c2, 19614 c1_stop_param, c2_stop_param, divergence_angle); 19615 19616 if(status == CUBIT_SUCCESS) 19617 { 19618 merge_end_points_on_curve1.append(v1->coordinates()); 19619 merge_end_points_on_curve2.append(v2->coordinates()); 19620 split_flags_for_curve1.append(CUBIT_FALSE); 19621 split_flags_for_curve2.append(CUBIT_FALSE); 19622 19623 // If we traversed the whole length of either curve and 19624 // we are told to merge the verts at both ends then 19625 // just add the verts at the other end and be done. 19626 if((full_c1 || full_c2) && merge_verts_at_both_ends) 19627 { 19628 split_flags_for_curve1.append(CUBIT_FALSE); 19629 split_flags_for_curve2.append(CUBIT_FALSE); 19630 if(c1_v1 == v1) 19631 merge_end_points_on_curve1.append(c1_v2->coordinates()); 19632 else 19633 merge_end_points_on_curve1.append(c1_v1->coordinates()); 19634 if(c2_v1 == v2) 19635 merge_end_points_on_curve2.append(c2_v2->coordinates()); 19636 else 19637 merge_end_points_on_curve2.append(c2_v1->coordinates()); 19638 all_done = true; 19639 } 19640 else 19641 { 19642 if(full_c2) 19643 { 19644 RefVertex *tmp_vert; 19645 if(c2_v1 == v2) 19646 tmp_vert = c2_v2; 19647 else 19648 tmp_vert = c2_v1; 19649 merge_end_points_on_curve2.append(tmp_vert->coordinates()); 19650 split_flags_for_curve2.append(CUBIT_FALSE); 19651 if(!full_c1) 19652 { 19653 CubitVector pos1; 19654 c1->closest_point_trimmed(tmp_vert->coordinates(), pos1); 19655 merge_end_points_on_curve1.append(pos1); 19656 split_flags_for_curve1.append(CUBIT_TRUE); 19657 } 19658 else 19659 { 19660 if(c1_v1 == v1) 19661 merge_end_points_on_curve1.append(c1_v2->coordinates()); 19662 else 19663 merge_end_points_on_curve1.append(c1_v1->coordinates()); 19664 split_flags_for_curve1.append(CUBIT_FALSE); 19665 } 19666 } 19667 else 19668 { 19669 split_flags_for_curve2.append(CUBIT_TRUE); 19670 if(full_c1) 19671 { 19672 split_flags_for_curve1.append(CUBIT_FALSE); 19673 if(c1_v1 == v1) 19674 { 19675 merge_end_points_on_curve1.append(c1_v2->coordinates()); 19676 // we need to imprint the end of c1 onto c2. 19677 CubitVector pos2; 19678 c2->closest_point_trimmed(c1_v2->coordinates(), pos2); 19679 merge_end_points_on_curve2.append(pos2); 19680 } 19681 else 19682 { 19683 merge_end_points_on_curve1.append(c1_v1->coordinates()); 19684 // we need to imprint the end of c1 onto c2. 19685 CubitVector pos2; 19686 c2->closest_point_trimmed(c1_v1->coordinates(), pos2); 19687 merge_end_points_on_curve2.append(pos2); 19688 } 19689 } 19690 else 19691 { 19692 split_flags_for_curve1.append(CUBIT_TRUE); 19693 // we need to imprint the end of c2 onto c1. 19694 CubitVector pos1; 19695 c1->position_from_u(c1_stop_param, pos1); 19696 merge_end_points_on_curve1.append(pos1); 19697 // we need to imprint the end of c1 onto c2. 19698 CubitVector pos2; 19699 c2->closest_point_trimmed(pos1, pos2); 19700 merge_end_points_on_curve2.append(pos2); 19701 } 19702 } 19703 } 19704 } 19705 } 19706 if(status == CUBIT_SUCCESS && !all_done) 19707 { 19708 if(merge_verts_at_both_ends) 19709 { 19710 // Process the next set of verts to merge. 19711 v1 = verts_to_merge.get_and_step(); 19712 v2 = verts_to_merge.get_and_step(); 19713 // Make sure v1 corresponds to c1 and v2 to c2. 19714 status = match_v1_to_c1(v1, v2, c1_v1, c1_v2, c2_v1, c2_v2); 19715 if(status == CUBIT_SUCCESS) 19716 { 19717 // Determine whether the verts are at the 19718 // beginning or end of curves. 19719 bool forward_c1, forward_c2; 19720 if(v1 == c1_v1) 19721 forward_c1 = true; 19722 else 19723 forward_c1 = false; 19724 if(v2 == c2_v1) 19725 forward_c2 = true; 19726 else 19727 forward_c2 = false; 19728 19729 double c1_stop_param, c2_stop_param; 19730 bool full_c1=false, full_c2=false; 19731 19732 status = find_overlap_region(c1, c2, v1, v2, forward_c1, forward_c2, full_c1, full_c2, 19733 c1_stop_param, c2_stop_param, divergence_angle); 19734 if(status == CUBIT_SUCCESS) 19735 { 19736 merge_end_points_on_curve1.append(v1->coordinates()); 19737 merge_end_points_on_curve2.append(v2->coordinates()); 19738 split_flags_for_curve1.append(CUBIT_FALSE); 19739 split_flags_for_curve2.append(CUBIT_FALSE); 19740 split_flags_for_curve1.append(CUBIT_TRUE); 19741 split_flags_for_curve2.append(CUBIT_TRUE); 19742 // we need to imprint the end of c2 onto c1. 19743 CubitVector pos1; 19744 c1->position_from_u(c1_stop_param, pos1); 19745 merge_end_points_on_curve1.append(pos1); 19746 // we need to imprint the end of c1 onto c2. 19747 CubitVector pos2; 19748 c2->position_from_u(c2_stop_param, pos2); 19749 merge_end_points_on_curve2.append(pos2); 19750 } 19751 } 19752 } 19753 } 19754 } 19755 19756 if(status == CUBIT_SUCCESS) 19757 { 19758 } 19759 19760 return status; 19761 } 19762 19763 CubitStatus GeometryModifyTool::tolerant_imprint( DLIList<Body*> &bodies, 19764 DLIList<Body*> &new_bodies, double overlap_tol, 19765 double imprint_tol, bool merge ) 19766 { 19767 //make sure all bodies are from the same modify engine 19768 DLIList<BodySM*> body_sm_list; 19769 GeometryModifyEngine* gme = common_modify_engine(bodies, body_sm_list); 19770 if ( !gme ) 19771 { 19772 PRINT_ERROR("Performing IMPRINT with volumes containing geometry\n" 19773 "from different modeling engines is not allowed.\n" 19774 "Delete uncommon geometry on these volumes before operation.\n\n"); 19775 return CUBIT_FAILURE; 19776 } 19777 19778 19779 //make sure that merge tolerance is not inapproiate for model 19780 int i; 19781 CubitBox bounding_box( CubitVector(0,0,0), 19782 CubitVector(CUBIT_DBL_MAX, 19783 CUBIT_DBL_MAX, 19784 CUBIT_DBL_MAX ) ); 19785 for( i=bodies.size(); i--; ) 19786 { 19787 CubitBox tmp_box = bodies.get_and_step()->bounding_box(); 19788 if(bounding_box.max_x() == CUBIT_DBL_MAX) 19789 bounding_box = tmp_box; 19790 else if( tmp_box.diagonal().length_squared() < 19791 bounding_box.diagonal().length_squared() ) 19792 bounding_box = tmp_box; 19793 } 19794 19795 //get the merge tolerance 19796 double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS; 19797 19798 //if the merge tolerance is greater than 1/10th the length of the 19799 //diagonal of the bounding box of the smallest volume, fail! 19800 double tenth_smallest_bbox = 0.1*(bounding_box.diagonal().length()); 19801 if( tolerance > tenth_smallest_bbox ) 19802 { 19803 PRINT_ERROR("Merge tolerance is set excessively high. Must be lower than %f\n", 19804 tenth_smallest_bbox ); 19805 PRINT_INFO(" (Merge tolerance must be less than than 1/10th of the diagonal\n" 19806 "of the bounding box of the smallest volume)\n"); 19807 return CUBIT_FAILURE; 19808 } 19809 19810 if( CubitUndo::get_undo_enabled() ) 19811 CubitUndo::save_state_with_cubit_file( bodies ); 19812 19813 // Propagate any merge tolerances on the bodies 19814 // propagate_merge_tolerance(bodies); 19815 19816 // Push the tolerance attributes 19817 // push_tolerance_attribute(bodies); 19818 19819 body_sm_list.clean_out(); 19820 DLIList<Body*> old_body_list; 19821 old_body_list += bodies; 19822 bodies.reset(); 19823 for( i=bodies.size(); i--; ) 19824 body_sm_list.append( bodies.get_and_step()->get_body_sm_ptr() ); 19825 19826 int process_composites = 0; 19827 if(contains_composites(bodies)) 19828 process_composites = 1; 19829 19830 if(process_composites) 19831 { 19832 // Push virtual attributes down to solid model topology before 19833 // doing the imprint. 19834 do_attribute_setup(); 19835 push_attributes_before_modify(body_sm_list); 19836 // This must be done after pushing the vg atts because it uses them. 19837 DLIList<TopologyBridge*> tb_list; 19838 CAST_LIST(body_sm_list, tb_list, TopologyBridge); 19839 push_named_attributes_to_curves_and_points(tb_list, "IMPRINTER"); 19840 push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL"); 19841 } 19842 19843 if (DEBUG_FLAG(95)) 19844 { 19845 PRINT_DEBUG_95( "Calculating local tolerances for tolerant imprinting.\n"); 19846 19847 //#ifndef _NDEBUG 19848 // LocalToleranceTool::instance()->print_local_tolerances( body_sm_list ); 19849 //#endif 19850 19851 // Calculate local tolerances at ref entities 19852 LocalToleranceTool::instance()->calculate_local_tolerances( body_sm_list ); 19853 19854 //#ifndef _NDEBUG 19855 // LocalToleranceTool::instance()->print_local_tolerances( body_sm_list ); 19856 //#endif 19857 } 19858 19859 // Call tolerant imprint 19860 DLIList<BodySM*> new_body_list; 19861 CubitStatus result = gme->tolerant_imprint( body_sm_list, new_body_list, overlap_tol, imprint_tol); 19862 19863 19864 if(result == CUBIT_FAILURE) 19865 { 19866 if(process_composites) 19867 { 19868 remove_pushed_attributes(new_body_list, bodies); 19869 do_attribute_cleanup(); 19870 } 19871 return result; 19872 } 19873 else 19874 { 19875 if(process_composites) 19876 { 19877 // Analyze the results and adjust virtual attributes as necessary. 19878 DLIList<TopologyBridge*> tb_list; 19879 CAST_LIST(new_body_list, tb_list, TopologyBridge); 19880 GeometryQueryTool::instance()->ige_attribute_after_imprinting(tb_list, bodies); 19881 19882 // Clean up attributes. 19883 remove_imprint_attributes_after_modify(body_sm_list, new_body_list); 19884 19885 // Restore the virtual geometry. 19886 restore_vg_after_modify(new_body_list, bodies, gme); 19887 remove_pushed_attributes(new_body_list, bodies); 19888 } 19889 } 19890 19891 // RANDY - HACK!! 19892 //for (int i = new_body_list.size(); i--;) 19893 //{ 19894 // clean_up_from_copy_failure(new_body_list.get_and_step()); 19895 //} 19896 19897 result = finish_sm_op( bodies, body_sm_list, new_bodies ); 19898 19899 if(process_composites) 19900 do_attribute_cleanup(); 19901 19902 if(result == CUBIT_FAILURE) 19903 { 19904 if( CubitUndo::get_undo_enabled() ) 19905 CubitUndo::remove_last_undo(); 19906 return CUBIT_FAILURE; 19907 } 19908 19909 if( merge ) 19910 MergeTool::instance()->merge_bodies( bodies ); 19911 19912 return CUBIT_SUCCESS; 19913 } 19914 19915 CubitStatus GeometryModifyTool::remove_curve_slivers( DLIList<Body*> &bodies, 19916 double lengthlimit ) 19917 { 19918 DLIList<BodySM*> body_sm_list; 19919 GeometryModifyEngine* gme = common_modify_engine(bodies, body_sm_list); 19920 if ( !gme ) 19921 { 19922 PRINT_ERROR("Curve sliver removal only supported on geometry\n"); 19923 return CUBIT_FAILURE; 19924 } 19925 19926 if( CubitUndo::get_undo_enabled() ) 19927 CubitUndo::save_state_with_cubit_file( bodies ); 19928 19929 CubitStatus status = CUBIT_FAILURE; 19930 DLIList<BodySM*> modified_bodies; 19931 int i; 19932 for( i=body_sm_list.size(); i--; ) 19933 { 19934 BodySM *tmp_body_sm = body_sm_list.get_and_step(); 19935 if( gme->remove_curve_slivers( tmp_body_sm, lengthlimit ) == CUBIT_SUCCESS ) 19936 { 19937 modified_bodies.append( tmp_body_sm ); 19938 status = CUBIT_SUCCESS; 19939 } 19940 } 19941 19942 if( status == CUBIT_FAILURE ) 19943 { 19944 PRINT_WARNING("Did not remove any sliver curves\n"); 19945 if( CubitUndo::get_undo_enabled() ) 19946 CubitUndo::remove_last_undo(); 19947 return CUBIT_FAILURE; 19948 } 19949 19950 DLIList<Body*> dummy_list; 19951 status = finish_sm_op( bodies, modified_bodies, dummy_list ); 19952 if( status == CUBIT_FAILURE ) 19953 { 19954 PRINT_WARNING("Did not remove any sliver curves\n"); 19955 if( CubitUndo::get_undo_enabled() ) 19956 CubitUndo::remove_last_undo(); 19957 return CUBIT_SUCCESS; 19958 } 19959 19960 return status; 19961 } 19962 19963 void GeometryModifyTool::split_surface_with_narrow_region(RefFace *face, 19964 DLIList<CubitVector> &split_pos1_list, 19965 DLIList<CubitVector> &split_pos2_list) 19966 { 19967 int k; 19968 if(split_pos1_list.size() > 0) 19969 { 19970 DLIList<DLIList<CubitVector*>*> vec_lists; 19971 DLIList<CubitVector*> pt_list; 19972 for(k=split_pos1_list.size(); k--;) 19973 { 19974 CubitVector split_pos1 = split_pos1_list.get_and_step(); 19975 CubitVector split_pos2 = split_pos2_list.get_and_step(); 19976 face->move_to_surface(split_pos1); 19977 face->move_to_surface(split_pos2); 19978 DLIList<CubitVector*> *vec_list = new DLIList<CubitVector*>; 19979 vec_list->append( new CubitVector(split_pos1)); 19980 vec_list->append( new CubitVector(split_pos2)); 19981 vec_lists.append( vec_list ); 19982 } 19983 19984 GeometryModifyTool::instance()->split_surface(face, 19985 pt_list, vec_lists ); 19986 19987 while( vec_lists.size() ) 19988 { 19989 DLIList<CubitVector*> *vec_list = vec_lists.pop(); 19990 while( vec_list->size() ) delete vec_list->pop(); 19991 delete vec_list; 19992 } 19993 /* 19994 while( pt_list.size() ) 19995 delete( pt_list.pop() ); 19996 */ 19997 } 19998 } 19999 20000 void GeometryModifyTool::fixup_merged_entities( DLIList<int> &merged_surface_ids, 20001 DLIList<int> &merged_curve_ids ) const 20002 { 20003 //use ids to find surviving merged entities 20004 DLIList<RefFace*> ref_face_list; 20005 DLIList<RefEdge*> ref_edge_list; 20006 20007 int i; 20008 //see what merged survived operation 20009 for( i=merged_surface_ids.size(); i--; ) 20010 { 20011 int face_id = merged_surface_ids.get_and_step(); 20012 RefFace *surviving_merged_face = RefEntityFactory::instance()->get_ref_face( face_id ); 20013 if( surviving_merged_face ) 20014 ref_face_list.append( surviving_merged_face ); 20015 } 20016 20017 //see what merged survived operation 20018 for( i=merged_curve_ids.size(); i--; ) 20019 { 20020 int edge_id = merged_curve_ids.get_and_step(); 20021 RefEdge *surviving_merged_edge = RefEntityFactory::instance()->get_ref_edge( edge_id ); 20022 if( surviving_merged_edge ) 20023 ref_edge_list.append( surviving_merged_edge ); 20024 } 20025 20026 //fix up merged faces -- some might need to be reversed 20027 for(i=ref_face_list.size(); i--; ) 20028 { 20029 RefFace *merged_face = ref_face_list.get_and_step(); 20030 BasicTopologyEntity *bte = static_cast<BasicTopologyEntity*>(merged_face); 20031 20032 //get the first bridge of the entity 20033 DLIList<TopologyBridge*> face_bridge_list; 20034 bte->bridge_manager()->get_bridge_list( face_bridge_list ); 20035 20036 //if there are 2 bridges in the list, it's still merged...do nothing 20037 if( face_bridge_list.size() > 1 ) 20038 continue; 20039 20040 //get the center of the RefFace 20041 CubitVector center = merged_face->center_point(); 20042 20043 //get the normal according to the RefFace 20044 CubitVector ref_face_normal = merged_face->normal_at( center ); 20045 20046 //get the normal at the center from the underlying Surface 20047 Surface *surface_ptr = CAST_TO( face_bridge_list.get(), Surface ); 20048 CubitVector surface_normal; 20049 surface_ptr->closest_point( center, NULL, &surface_normal ); 20050 20051 //if normals are opposite, flip sense of surface_ptr 20052 if( fabs(ref_face_normal.interior_angle( surface_normal ) - 180 ) < 0.1 ) 20053 merged_face->reverse_normal(); 20054 20055 //One more thing.....if surface is a composite, update the graphics 20056 //on the hidden curve...could have been deleted. 20057 if ( GeometryQueryTool::instance()->ige_is_composite( surface_ptr ) ) 20058 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_MODIFIED, merged_face)); 20059 } 20060 20061 //fix up merged edges -- some might need to be reversed 20062 for(i=ref_edge_list.size(); i--; ) 20063 { 20064 RefEdge *merged_edge = ref_edge_list.get_and_step(); 20065 BasicTopologyEntity *bte = static_cast<BasicTopologyEntity*>(merged_edge); 20066 20067 //get the first bridge of the entity 20068 DLIList<TopologyBridge*> edge_bridge_list; 20069 bte->bridge_manager()->get_bridge_list( edge_bridge_list ); 20070 20071 //get start/end points of the edge 20072 CubitVector edge_start_point = merged_edge->start_vertex()->coordinates(); 20073 CubitVector edge_end_point = merged_edge->end_vertex()->coordinates(); 20074 20075 //get start/end point of the curve 20076 edge_bridge_list.reset(); 20077 Curve *curve_ptr = CAST_TO( edge_bridge_list.get(), Curve); 20078 DLIList<TBPoint*> tmp_points; 20079 curve_ptr->points( tmp_points ); 20080 CubitVector curve_start_point = tmp_points.get_and_step()->coordinates(); 20081 CubitVector curve_end_point = tmp_points.get_and_step()->coordinates(); 20082 20083 //check to see if curve sense needs to be reversed 20084 if( edge_start_point.distance_between( curve_start_point ) < GEOMETRY_RESABS && 20085 edge_end_point.distance_between( curve_end_point ) < GEOMETRY_RESABS ) 20086 { 20087 //do nothing...everything is fine 20088 continue; 20089 } 20090 else 20091 { 20092 if( edge_start_point.distance_between( curve_end_point ) < GEOMETRY_RESABS && 20093 edge_end_point.distance_between( curve_start_point ) < GEOMETRY_RESABS ) 20094 { 20095 //switch sense of ref entity 20096 merged_edge->reverse_tangent(); 20097 } 20098 } 20099 } 20100 } 20101 20102 void GeometryModifyTool::get_merged_curve_and_surface_ids( 20103 DLIList<Body*> &bodies, 20104 DLIList<int> &merged_surface_ids, 20105 DLIList<int> &merged_curve_ids ) const 20106 { 20107 int i; 20108 for( i=bodies.size(); i--; ) 20109 { 20110 DLIList<RefEntity*> merged_children; 20111 20112 MergeTool::instance()->contains_merged_children( bodies.get_and_step(), 20113 merged_children ); 20114 20115 int j; 20116 for( j=merged_children.size(); j--; ) 20117 { 20118 RefEntity *ref_ent = merged_children.get_and_step(); 20119 20120 RefFace *ref_face = CAST_TO( ref_ent, RefFace ); 20121 20122 if( ref_face ) 20123 merged_surface_ids.append( ref_face->id() ); 20124 else 20125 { 20126 RefEdge *ref_edge = CAST_TO( ref_ent, RefEdge ); 20127 20128 if( ref_edge ) 20129 merged_curve_ids.append( ref_edge->id() ); 20130 } 20131 } 20132 } 20133 } 20134 20135 void GeometryModifyTool::plane_preview(DLIList<Body*>& body_list, 20136 const CubitVector &pt1, 20137 const CubitVector &pt2, 20138 const CubitVector &pt3) 20139 { 20140 CubitPlane plane; 20141 if( plane.mk_plane_with_points( pt1, pt2, pt3) == CUBIT_FAILURE) 20142 { 20143 PRINT_INFO( "Unable to create plane from given information.\n" ); 20144 return ; 20145 } 20146 20147 CubitBox bounding_box; 20148 Body* body_ptr = body_list.get_and_step(); 20149 bounding_box = body_ptr->bounding_box(); 20150 20151 int i; 20152 for( i=1; i<body_list.size(); i++ ) 20153 { 20154 body_ptr = body_list.get_and_step(); 20155 bounding_box |= body_ptr->bounding_box(); 20156 } 20157 20158 int extension_type = 1; 20159 double extension = 10; //10% 20160 CubitVector p1, p2, p3, p4; 20161 20162 if( AnalyticGeometryTool::instance()-> 20163 min_pln_box_int_corners( plane, bounding_box, extension_type, 20164 extension, p1, p2, p3, p4 ) == CUBIT_FAILURE ) 20165 { 20166 PRINT_INFO( "Unable to create plane from given information.\n" ); 20167 return ; 20168 } 20169 20170 GPoint gp[4]; 20171 gp[0].x=p1.x(); gp[0].y=p1.y(); gp[0].z=p1.z(); 20172 gp[1].x=p2.x(); gp[1].y=p2.y(); gp[1].z=p2.z(); 20173 gp[2].x=p3.x(); gp[2].y=p3.y(); gp[2].z=p3.z(); 20174 gp[3].x=p4.x(); gp[3].y=p4.y(); gp[3].z=p4.z(); 20175 20176 // clear previous previews 20177 GfxPreview::clear(); 20178 20179 // Get the color to draw in 20180 int color = CUBIT_BLUE_INDEX; 20181 GfxPreview::draw_quad(gp, color); 20182 GfxPreview::flush(); 20183 return; 20184 } 20185 20186 void GeometryModifyTool::march_using_planes(CubitVector &point_on_surf, 20187 RefFace *surf, 20188 CubitVector &march_dir, 20189 double step_size, 20190 DLIList<CubitVector> &horizontal_points, 20191 DLIList<CubitVector> &vertical_points) 20192 { 20193 CubitVector surf_norm = surf->normal_at(point_on_surf); 20194 CubitVector plane_norm = march_dir * surf_norm; 20195 GeometryModifyEngine *gme = get_engine((TopologyBridge*)surf->get_surface_ptr()); 20196 if(gme) 20197 { 20198 CubitPlane plane(plane_norm, point_on_surf); 20199 CubitBox bbox = surf->ref_volume()->bounding_box(); 20200 CubitVector p1, p2, p3, p4; 20201 AnalyticGeometryTool::instance()->min_pln_box_int_corners( plane, bbox, 1, 20202 10.0, p1, p2, p3, p4, CUBIT_TRUE ); 20203 Body *plane_body = GeometryModifyTool::instance()->planar_sheet( p1, p2, p3, p4 ); 20204 Body *model_body_copy = GeometryModifyTool::instance()->copy_body(surf->body()); 20205 DLIList<Body*> from_body_list, new_body_list; 20206 from_body_list.append(plane_body); 20207 from_body_list.append(model_body_copy); 20208 GeometryModifyTool::imprint(from_body_list, new_body_list, CUBIT_FALSE); 20209 for(int i=0; i<new_body_list.size(); i++) 20210 { 20211 if(new_body_list[i] == plane_body) 20212 { 20213 trace_out_curves(plane_body, point_on_surf, march_dir, 20214 step_size, horizontal_points, vertical_points); 20215 /* 20216 GfxDebug::clear(); 20217 DLIList<RefEdge*> plane_curves; 20218 plane_body->ref_edges(plane_curves); 20219 for(int j=0; j<plane_curves.size(); j++) 20220 { 20221 GfxDebug::draw_ref_edge(plane_curves[j], CUBIT_RED_INDEX); 20222 } 20223 GfxDebug::flush(); 20224 GfxDebug::mouse_xforms(); 20225 */ 20226 } 20227 else 20228 GeometryQueryTool::instance()->delete_single_Body(new_body_list[i]); 20229 } 20230 } 20231 } 20232 20233 void GeometryModifyTool::trace_out_curves(Body *plane_body, 20234 CubitVector &start_point, 20235 CubitVector &march_dir, 20236 double step_size, 20237 DLIList<CubitVector> &horizontal_points, 20238 DLIList<CubitVector> &vertical_points) 20239 { 20240 // Find a curve that the start point is on. 20241 DLIList<RefEdge*> curves; 20242 plane_body->ref_edges(curves); 20243 DLIList<RefEdge*> interior_curves; 20244 for(int i=0; i<curves.size(); i++) 20245 { 20246 RefEdge *cur_curve = curves[i]; 20247 DLIList<RefFace*> curve_surfs; 20248 cur_curve->ref_faces(curve_surfs); 20249 if(curve_surfs.size() == 2) 20250 interior_curves.append(cur_curve); 20251 } 20252 RefEdge *start_curve = NULL; 20253 for(int i=0; i<interior_curves.size(); i++) 20254 { 20255 CubitVector closest; 20256 RefEdge *cur_curve = interior_curves[i]; 20257 cur_curve->closest_point_trimmed(start_point, closest); 20258 if(start_point.about_equal(closest)) 20259 { 20260 start_curve = cur_curve; 20261 break; 20262 } 20263 } 20264 if(start_curve) 20265 { 20266 20267 } 20268 } 20269 20270 void GeometryModifyTool::march_path_to_discover_horizontal(CubitVector &start_pos, 20271 CubitVector &sweep_dir, 20272 RefFace *start_face, 20273 CubitVector &march_dir, // should be normalized 20274 double &step_size, 20275 DLIList<CubitVector> &final_points, 20276 DLIList<RefFace*> &ending_faces) 20277 { 20278 double cos_45 = 0.70710678118654752440084436210485; 20279 double geo_tol = GeometryQueryTool::instance()->get_sme_resabs_tolerance(); 20280 CubitVector point_on_surf = start_pos; 20281 RefVolume *v = start_face->ref_volume(); 20282 RefFace *cur_face = start_face; 20283 20284 RefEdge *snap_edge = NULL; 20285 bool snapped_to_edge_last_time = false; 20286 bool turned = false; 20287 CubitVector old_pos = point_on_surf; 20288 while(!turned) 20289 { 20290 CubitVector new_pos; 20291 if(snapped_to_edge_last_time) 20292 { 20293 // Just set the new position to the position on the 20294 // edge. This will force us to jump out without doing 20295 // anything and then on the next loop we will start 20296 // onto the new face. 20297 new_pos = old_pos; 20298 snapped_to_edge_last_time = false; 20299 continue; 20300 } 20301 else 20302 { 20303 // Calculate a new step along the vector. 20304 new_pos = old_pos + step_size * march_dir; 20305 } 20306 20307 cur_face->get_surface_ptr()->closest_point_trimmed(new_pos, point_on_surf); 20308 20309 CubitVector norm = cur_face->normal_at(point_on_surf, v); 20310 if(sweep_dir % norm < cos_45) 20311 { 20312 turned = true; 20313 } 20314 else 20315 { 20316 bool snapping_to_edge = true; 20317 CubitVector proj_dir = point_on_surf - new_pos; 20318 double proj_dist = proj_dir.length(); 20319 if(proj_dist < geo_tol) 20320 snapping_to_edge = false; 20321 else 20322 { 20323 proj_dir /= proj_dist; 20324 double dot = proj_dir % norm; 20325 if(dot > .99 || dot < -.99) 20326 snapping_to_edge = false; 20327 } 20328 if(!snapping_to_edge) 20329 { 20330 snap_edge = NULL; 20331 // didn't snap to boundary 20332 old_pos = point_on_surf; 20333 final_points.append(point_on_surf); 20334 } 20335 else 20336 { 20337 // probably snapped to the boundary of this face 20338 DLIList<RefEdge*> face_edges; 20339 RefEdge *best_edge = NULL; 20340 cur_face->ref_edges(face_edges); 20341 int i; 20342 DLIList<RefEdge*> possible_edges; 20343 CubitVector closest; 20344 for(i=face_edges.size(); i>0; i--) 20345 { 20346 RefEdge *e = face_edges.get_and_step(); 20347 e->closest_point_trimmed(point_on_surf, closest); 20348 double cur_dist = (closest - point_on_surf).length(); 20349 if(cur_dist < geo_tol) 20350 { 20351 possible_edges.append(e); 20352 } 20353 } 20354 if(possible_edges.size() == 1) 20355 best_edge = possible_edges.get(); 20356 else if(possible_edges.size() > 1) 20357 { 20358 int h; 20359 double smallest_dist = CUBIT_DBL_MAX; 20360 for(h=possible_edges.size(); h>0; h--) 20361 { 20362 RefEdge *ce = possible_edges.get_and_step(); 20363 ce->closest_point_trimmed(old_pos, closest); 20364 double cur_dist = (old_pos-closest).length(); 20365 if(cur_dist < smallest_dist) 20366 { 20367 smallest_dist = cur_dist; 20368 best_edge = ce; 20369 } 20370 } 20371 } 20372 if(best_edge) 20373 { 20374 if(snap_edge && snap_edge == best_edge) 20375 { 20376 final_points.append(point_on_surf); 20377 old_pos = point_on_surf; 20378 snapped_to_edge_last_time = true; 20379 } 20380 else 20381 { 20382 snap_edge = best_edge; 20383 cur_face = best_edge->other_face(cur_face, v); 20384 CubitVector old_pos_save = old_pos; 20385 old_pos = closest; 20386 i = 0; 20387 snapped_to_edge_last_time = true; 20388 20389 GeometryModifyEngine *gme = get_engine((TopologyBridge*)best_edge->get_curve_ptr()); 20390 if(gme) 20391 { 20392 TBPoint *pt1 = gme->make_Point(old_pos_save); 20393 TBPoint *pt2 = gme->make_Point(new_pos); 20394 CubitVector const* pt3 = NULL; 20395 Curve *crv = gme->make_Curve(STRAIGHT_CURVE_TYPE, pt1, pt2, pt3 ); 20396 if(crv) 20397 { 20398 CubitVector pos1, pos2; 20399 double dist; 20400 GeometryQueryTool::instance()->entity_entity_distance(crv, best_edge->get_curve_ptr(), pos1, 20401 pos2, dist); 20402 old_pos = pos2; 20403 delete crv; 20404 delete pt1; 20405 delete pt2; 20406 final_points.append(old_pos); 20407 } 20408 } 20409 } 20410 } 20411 } 20412 } 20413 } 20414 ending_faces.append(cur_face); 20415 } 20416 20417 void GeometryModifyTool::march_path_to_discover_vertical(CubitVector &start_pos, 20418 CubitVector &sweep_dir, 20419 RefFace *start_face, 20420 CubitVector &march_dir, // should be normalized 20421 double &step_size, 20422 DLIList<CubitVector> &final_points, 20423 DLIList<RefFace*> &ending_faces) 20424 { 20425 double cos_45 = 0.70710678118654752440084436210485; 20426 double geo_tol = GeometryQueryTool::instance()->get_sme_resabs_tolerance(); 20427 CubitVector point_on_surf = start_pos; 20428 RefVolume *v = start_face->ref_volume(); 20429 RefFace *cur_face = start_face; 20430 20431 RefEdge *snap_edge = NULL; 20432 bool snapped_to_edge_last_time = false; 20433 bool turned = false; 20434 CubitVector old_pos = point_on_surf; 20435 while(!turned) 20436 { 20437 CubitVector new_pos; 20438 if(snapped_to_edge_last_time) 20439 { 20440 // Just set the new position to the position on the 20441 // edge. This will force us to jump out without doing 20442 // anything and then on the next loop we will start 20443 // onto the new face. 20444 new_pos = old_pos; 20445 snapped_to_edge_last_time = false; 20446 //snap_edge = NULL; 20447 continue; 20448 } 20449 else 20450 { 20451 // Calculate a new step along the vector. 20452 new_pos = old_pos + step_size * march_dir; 20453 } 20454 20455 cur_face->get_surface_ptr()->closest_point_trimmed(new_pos, point_on_surf); 20456 20457 int d = 0; 20458 if(d) 20459 { 20460 GfxDebug::draw_point(new_pos, CUBIT_BLUE_INDEX); 20461 GfxDebug::draw_point(point_on_surf, CUBIT_RED_INDEX); 20462 GfxDebug::flush(); 20463 GfxDebug::mouse_xforms(); 20464 } 20465 20466 CubitVector norm = cur_face->normal_at(point_on_surf, v); 20467 double tmp_dot = sweep_dir % norm; 20468 if(tmp_dot > cos_45 || tmp_dot < -cos_45) 20469 { 20470 turned = true; 20471 } 20472 else 20473 { 20474 bool snapping_to_edge = true; 20475 CubitVector proj_dir = point_on_surf - new_pos; 20476 double proj_dist = proj_dir.length(); 20477 if(proj_dist < geo_tol) 20478 snapping_to_edge = false; 20479 else 20480 { 20481 proj_dir /= proj_dist; 20482 double dot = proj_dir % norm; 20483 if(dot > .99 || dot < -.99) 20484 snapping_to_edge = false; 20485 } 20486 if(!snapping_to_edge) 20487 { 20488 snap_edge = NULL; 20489 // didn't snap to boundary 20490 old_pos = point_on_surf; 20491 final_points.append(point_on_surf); 20492 } 20493 else 20494 { 20495 // probably snapped to the boundary of this face 20496 DLIList<RefEdge*> face_edges; 20497 RefEdge *best_edge = NULL; 20498 CubitVector best_pos; 20499 cur_face->ref_edges(face_edges); 20500 DLIList<RefEdge*> possible_edges; 20501 CubitVector closest; 20502 for(int i=face_edges.size(); i>0; i--) 20503 { 20504 RefEdge *e = face_edges.get_and_step(); 20505 e->closest_point_trimmed(point_on_surf, closest); 20506 double cur_dist = (closest - point_on_surf).length(); 20507 if(cur_dist < geo_tol) 20508 { 20509 // If there are more than one edge that are coincident with the point 20510 // choose the one whose tangent is most normal to the direction we are 20511 // marching. Switching onto the corresponding face should be best. 20512 if(best_edge) 20513 { 20514 CubitVector best_edge_tan, cur_edge_tan; 20515 best_edge->tangent(point_on_surf, best_edge_tan); 20516 e->tangent(point_on_surf, cur_edge_tan); 20517 if(fabs(best_edge_tan % march_dir) > fabs(cur_edge_tan % march_dir)) 20518 best_edge = e; 20519 } 20520 else 20521 best_edge = e; 20522 } 20523 } 20524 if(best_edge) 20525 { 20526 if(snap_edge && snap_edge == best_edge) 20527 { 20528 final_points.append(point_on_surf); 20529 old_pos = point_on_surf; 20530 snapped_to_edge_last_time = true; 20531 } 20532 else 20533 { 20534 snap_edge = best_edge; 20535 cur_face = best_edge->other_face(cur_face, v); 20536 CubitVector old_pos_save = old_pos; 20537 old_pos = best_pos; 20538 snapped_to_edge_last_time = true; 20539 20540 GeometryModifyEngine *gme = get_engine((TopologyBridge*)best_edge->get_curve_ptr()); 20541 if(gme) 20542 { 20543 TBPoint *pt1 = gme->make_Point(old_pos_save); 20544 TBPoint *pt2 = gme->make_Point(new_pos); 20545 CubitVector const* pt3 = NULL; 20546 Curve *crv = gme->make_Curve(STRAIGHT_CURVE_TYPE, pt1, pt2, pt3 ); 20547 if(crv) 20548 { 20549 CubitVector pos1, pos2; 20550 double dist; 20551 GeometryQueryTool::instance()->entity_entity_distance(crv, best_edge->get_curve_ptr(), pos1, 20552 pos2, dist); 20553 old_pos = pos2; 20554 delete crv; 20555 delete pt1; 20556 delete pt2; 20557 final_points.append(old_pos); 20558 } 20559 } 20560 } 20561 } 20562 } 20563 } 20564 } 20565 ending_faces.append(cur_face); 20566 } 20567 20568 CubitStatus GeometryModifyTool::stitch( DLIList<Body*> &bodies_to_stitch, 20569 DLIList<Body*> &result_list, 20570 bool tighten_gaps, 20571 double tolerance ) 20572 { 20573 if (!okay_to_modify( bodies_to_stitch, "STITCH" )) 20574 return CUBIT_FAILURE; 20575 20576 //get all the BodySMs from 'bodies_to_stitch' 20577 int i; 20578 for( i=bodies_to_stitch.size(); i--; ) 20579 { 20580 Body *tmp_body = bodies_to_stitch.get_and_step(); 20581 if( !tmp_body->is_sheet_body() ) 20582 { 20583 PRINT_ERROR("Can't stitch body %d. It's a solid body\n", tmp_body->id() ); 20584 return CUBIT_FAILURE; 20585 } 20586 } 20587 20588 DLIList<TopologyEntity*> entity_list(bodies_to_stitch.size()); 20589 DLIList<TopologyBridge*> bridge_list(bodies_to_stitch.size()); 20590 DLIList<BodySM*> bodysm_list(bodies_to_stitch.size()); 20591 CAST_LIST_TO_PARENT(bodies_to_stitch, entity_list); 20592 GeometryModifyEngine *gme = common_modify_engine(entity_list, bridge_list); 20593 20594 if( entity_list.size() != bridge_list.size() ) 20595 { 20596 PRINT_ERROR("Cannot stitch entities of different geometry engines.\n"); 20597 return CUBIT_FAILURE; 20598 } 20599 20600 if( CubitUndo::get_undo_enabled() ) 20601 CubitUndo::save_state_with_cubit_file( bodies_to_stitch ); 20602 20603 CAST_LIST(bridge_list, bodysm_list, BodySM); 20604 DLIList<BodySM*> new_bodies; 20605 CubitStatus result = gme->stitch( bodysm_list, new_bodies, tighten_gaps, tolerance ); 20606 20607 if( result == CUBIT_FAILURE && CubitUndo::get_undo_enabled() ) 20608 CubitUndo::remove_last_undo(); 20609 20610 if (!finish_sm_op(bodies_to_stitch, new_bodies, result_list)) 20611 { 20612 result = CUBIT_FAILURE; 20613 CubitUndo::remove_last_undo(); 20614 } 20615 20616 if( CubitUndo::get_undo_enabled() ) 20617 { 20618 if( result == CUBIT_SUCCESS ) 20619 CubitUndo::note_result_bodies( result_list ); 20620 else 20621 CubitUndo::remove_last_undo(); 20622 } 20623 20624 return result; 20625 } 20626 20627 20628 20629 CubitStatus GeometryModifyTool::discover_topology(RefFace *surf, CubitVector &pos, 20630 double &step_size, 20631 int num_subdivisions) 20632 { 20633 CubitStatus ret = CUBIT_SUCCESS; 20634 20635 CubitVector point_on_surf; 20636 surf->get_surface_ptr()->closest_point_trimmed(pos, point_on_surf); 20637 RefVolume *v = surf->ref_volume(); 20638 CubitVector norm = surf->normal_at(point_on_surf, v); 20639 CubitVector march_dir = norm * CubitVector(1,0,0); 20640 if(march_dir.length() < .001) 20641 { 20642 march_dir = norm * CubitVector(0,1,0); 20643 if(march_dir.length() < .001) 20644 { 20645 march_dir = norm * CubitVector(0,0,1); 20646 if(march_dir.length() < .001) 20647 { 20648 PRINT_ERROR("Couldn't find a good march direction.\n"); 20649 ret = CUBIT_FAILURE; 20650 } 20651 } 20652 } 20653 20654 if(ret == CUBIT_SUCCESS) 20655 { 20656 int new_approach = 0; 20657 if(new_approach) 20658 { 20659 // Get initial 4 directions. 20660 march_dir.normalize(); 20661 DLIList<CubitVector> march_directions; 20662 CubitVector v1 = march_dir; 20663 CubitVector v3 = -march_dir; 20664 CubitVector v2 = norm*march_dir; 20665 march_directions.append(v1); 20666 march_directions.append(v2); 20667 march_directions.append(v3); 20668 20669 // Now subdivide directions further if requested. 20670 for(int i=0; i<num_subdivisions; ++i) 20671 { 20672 DLIList<CubitVector> tmp_list; 20673 int list_size = march_directions.size(); 20674 for(int j=0; j<list_size-1; j++) 20675 { 20676 CubitVector dir1 = march_directions[j]; 20677 CubitVector dir2 = march_directions[(j+1)%list_size]; 20678 CubitVector mid = dir1 + dir2; 20679 mid.normalize(); 20680 tmp_list.append(dir1); 20681 tmp_list.append(mid); 20682 } 20683 tmp_list.append(march_directions[list_size-1]); 20684 march_directions = tmp_list; 20685 } 20686 DLIList<DLIList<CubitVector> > horizontal_points, vertical_points; 20687 DLIList<RefFace*> horiz_ending_faces, vert_ending_faces; 20688 for(int i=0; i<march_directions.size()-1; i++) 20689 { 20690 DLIList<CubitVector> new_list; 20691 horizontal_points.append(new_list); 20692 vertical_points.append(new_list); 20693 march_using_planes(point_on_surf, surf, march_directions[i], step_size, horizontal_points[i], vertical_points[i]); 20694 } 20695 } 20696 else 20697 { 20698 // Get initial 4 directions. 20699 march_dir.normalize(); 20700 DLIList<CubitVector> march_directions; 20701 CubitVector v1 = march_dir; 20702 CubitVector v3 = -march_dir; 20703 CubitVector v2 = norm*march_dir; 20704 CubitVector v4 = -v2; 20705 march_directions.append(v1); 20706 march_directions.append(v2); 20707 march_directions.append(v3); 20708 march_directions.append(v4); 20709 20710 // Now subdivide directions further if requested. 20711 for(int i=0; i<num_subdivisions; ++i) 20712 { 20713 DLIList<CubitVector> tmp_list; 20714 int list_size = march_directions.size(); 20715 for(int j=0; j<list_size; j++) 20716 { 20717 CubitVector dir1 = march_directions[j]; 20718 CubitVector dir2 = march_directions[(j+1)%list_size]; 20719 CubitVector mid = dir1 + dir2; 20720 mid.normalize(); 20721 tmp_list.append(dir1); 20722 tmp_list.append(mid); 20723 } 20724 march_directions = tmp_list; 20725 } 20726 DLIList<DLIList<CubitVector> > horizontal_points, vertical_points; 20727 DLIList<RefFace*> horiz_ending_faces, vert_ending_faces; 20728 for(int i=0; i<march_directions.size(); i++) 20729 { 20730 DLIList<CubitVector> new_list; 20731 new_list.append(point_on_surf); 20732 horizontal_points.append(new_list); 20733 march_path_to_discover_horizontal(point_on_surf, norm, surf, march_directions[i], step_size, horizontal_points[i], horiz_ending_faces); 20734 } 20735 CubitVector new_dir = -norm; 20736 for(int i=0; i<march_directions.size(); i++) 20737 { 20738 CubitVector start_pos = horizontal_points[i].last_item(); 20739 DLIList<CubitVector> new_list; 20740 new_list.append(start_pos); 20741 vertical_points.append(new_list); 20742 march_path_to_discover_vertical(start_pos, norm, horiz_ending_faces[i], new_dir, step_size, vertical_points[i], vert_ending_faces); 20743 // GfxDebug::draw_point(vertical_points[i].last_item(), CUBIT_GREEN_INDEX); 20744 // GfxDebug::flush(); 20745 } 20746 20747 // Draw lines traced out by marching directions 20748 for(int i=0; i<horizontal_points.size(); i++) 20749 { 20750 int size1 = horizontal_points[i].size(); 20751 for(int j=0; j<size1-1; j++) 20752 { 20753 GfxDebug::draw_line(horizontal_points[i][j], 20754 horizontal_points[i][j+1], 20755 CUBIT_WHITE_INDEX); 20756 } 20757 } 20758 for(int i=0; i<vertical_points.size(); i++) 20759 { 20760 int size1 = vertical_points[i].size(); 20761 for(int j=0; j<size1-1; j++) 20762 { 20763 GfxDebug::draw_line(vertical_points[i][j], 20764 vertical_points[i][j+1], 20765 CUBIT_YELLOW_INDEX); 20766 } 20767 } 20768 // Draw new topology 20769 int size1 = horizontal_points.size(); 20770 for(int i=0; i<size1; i++) 20771 { 20772 GfxDebug::draw_line(horizontal_points[i].last_item(), 20773 horizontal_points[(i+1)%size1].last_item(), 20774 CUBIT_RED_INDEX); 20775 } 20776 size1 = vertical_points.size(); 20777 for(int i=0; i<size1; i++) 20778 { 20779 GfxDebug::draw_line(vertical_points[i].last_item(), 20780 vertical_points[(i+1)%size1].last_item(), 20781 CUBIT_RED_INDEX); 20782 } 20783 GfxDebug::flush(); 20784 } 20785 } 20786 20787 return ret; 20788 } 20789 20790 void GeometryModifyTool::subdivide_pie(CubitVector &dir1, CubitVector &dir2, int num_subdivisions, 20791 DLIList<CubitVector> &all_directions) 20792 { 20793 if(num_subdivisions > 0) 20794 { 20795 CubitVector mid = dir1 + dir2; 20796 mid.normalize(); 20797 all_directions.append(mid); 20798 if(num_subdivisions > 1) 20799 { 20800 subdivide_pie(dir1, mid, num_subdivisions-1, all_directions); 20801 subdivide_pie(mid, dir2, num_subdivisions-1, all_directions); 20802 } 20803 } 20804 } 20805 20806 Body* GeometryModifyTool::create_rectangle_surface( double width, double height, CubitVector plane ) 20807 { 20808 if(0 == gmeList.size()) 20809 { 20810 PRINT_WARNING("No active geometry engine.\n"); 20811 return NULL; 20812 } 20813 20814 if( width <= GEOMETRY_RESABS || height <= GEOMETRY_RESABS ) 20815 { 20816 PRINT_ERROR("Values must be positive\n"); 20817 return NULL; 20818 } 20819 20820 if( CubitUndo::get_undo_enabled() ) 20821 CubitUndo::save_state(); 20822 20823 BodySM *sheet_body_sm = NULL; 20824 CubitStatus status = gmeList.get()->create_rectangle_surface(width, height, plane, sheet_body_sm ); 20825 20826 if( status == CUBIT_FAILURE ) 20827 { 20828 if(CubitUndo::get_undo_enabled()) 20829 CubitUndo::remove_last_undo(); 20830 return NULL; 20831 } 20832 20833 Body *new_body = NULL; 20834 if( sheet_body_sm ) 20835 new_body = GeometryQueryTool::instance()->make_Body(sheet_body_sm); 20836 20837 if (new_body) 20838 { 20839 if(CubitUndo::get_undo_enabled()) 20840 CubitUndo::note_result_body(new_body); 20841 status = CUBIT_SUCCESS; 20842 } 20843 else 20844 { 20845 if(CubitUndo::get_undo_enabled()) 20846 CubitUndo::remove_last_undo(); 20847 status = CUBIT_FAILURE; 20848 } 20849 20850 return new_body; 20851 } 20852 20853 Body* GeometryModifyTool::create_parallelogram_surface( RefVertex *v1, 20854 RefVertex *v2, 20855 RefVertex *v3 ) 20856 { 20857 if(0 == gmeList.size()) 20858 { 20859 PRINT_WARNING("No active geometry engine.\n"); 20860 return NULL; 20861 } 20862 20863 GeometryModifyEngine *GMEPtr = get_engine( v1->get_point_ptr() ); 20864 20865 if( GMEPtr != get_engine( v2->get_point_ptr() ) ) 20866 { 20867 PRINT_INFO("Vertices are not from same modeling engine.\n"); 20868 return NULL; 20869 } 20870 if( GMEPtr != get_engine( v3->get_point_ptr() ) ) 20871 { 20872 PRINT_INFO("Vertices are not from same modeling engine.\n"); 20873 return NULL; 20874 } 20875 20876 TBPoint *pt1, *pt2, *pt3; 20877 20878 DLIList<RefVertex*> free_ref_vertices; 20879 if( v1->num_parent_ref_entities() == 0 ) 20880 { 20881 free_ref_vertices.append( v1 ); 20882 pt1 = v1->get_point_ptr(); 20883 } 20884 else 20885 pt1 = GMEPtr->make_Point( v1->coordinates() ); 20886 20887 if( v2->num_parent_ref_entities() == 0 ) 20888 { 20889 free_ref_vertices.append( v2 ); 20890 pt2 = v2->get_point_ptr(); 20891 } 20892 else 20893 pt2 = GMEPtr->make_Point( v2->coordinates() ); 20894 20895 if( v3->num_parent_ref_entities() == 0 ) 20896 { 20897 free_ref_vertices.append( v3 ); 20898 pt3 = v3->get_point_ptr(); 20899 } 20900 else 20901 pt3 = GMEPtr->make_Point( v3->coordinates() ); 20902 20903 if( CubitUndo::get_undo_enabled() ) 20904 { 20905 if( free_ref_vertices.size() ) 20906 CubitUndo::save_state_with_cubit_file( free_ref_vertices, true ); 20907 else 20908 CubitUndo::save_state(); 20909 } 20910 20911 BodySM *sheet_body_sm = NULL; 20912 CubitStatus status = GMEPtr->create_parallelogram_surface(pt1, pt2, pt3, sheet_body_sm ); 20913 20914 if( status == CUBIT_FAILURE ) 20915 { 20916 if(CubitUndo::get_undo_enabled()) 20917 CubitUndo::remove_last_undo(); 20918 return NULL; 20919 } 20920 20921 Body *new_body = NULL; 20922 if( sheet_body_sm ) 20923 new_body = GeometryQueryTool::instance()->make_Body(sheet_body_sm); 20924 20925 if (new_body) 20926 { 20927 if(CubitUndo::get_undo_enabled()) 20928 CubitUndo::note_result_body(new_body); 20929 } 20930 else 20931 { 20932 if(CubitUndo::get_undo_enabled()) 20933 CubitUndo::remove_last_undo(); 20934 } 20935 20936 return new_body; 20937 } 20938 20939 Body* GeometryModifyTool::create_circle_surface( double radius, CubitVector plane ) 20940 { 20941 if(0 == gmeList.size()) 20942 { 20943 PRINT_WARNING("No active geometry engine.\n"); 20944 return NULL; 20945 } 20946 20947 if( radius <= GEOMETRY_RESABS ) 20948 { 20949 PRINT_ERROR("Values must be positive\n"); 20950 return NULL; 20951 } 20952 20953 if( CubitUndo::get_undo_enabled() ) 20954 CubitUndo::save_state(); 20955 20956 BodySM *sheet_body_sm = NULL; 20957 CubitStatus status = gmeList.get()->create_circle_surface(radius, plane, sheet_body_sm ); 20958 20959 if( status == CUBIT_FAILURE ) 20960 { 20961 if(CubitUndo::get_undo_enabled()) 20962 CubitUndo::remove_last_undo(); 20963 return NULL; 20964 } 20965 20966 Body *new_body = NULL; 20967 if( sheet_body_sm ) 20968 new_body = GeometryQueryTool::instance()->make_Body(sheet_body_sm); 20969 20970 if (new_body) 20971 { 20972 if(CubitUndo::get_undo_enabled()) 20973 CubitUndo::note_result_body(new_body); 20974 } 20975 else 20976 { 20977 if(CubitUndo::get_undo_enabled()) 20978 CubitUndo::remove_last_undo(); 20979 } 20980 20981 return new_body; 20982 } 20983 20984 Body* GeometryModifyTool::create_circle_surface( RefVertex *v1, 20985 RefVertex *v2, 20986 RefVertex *v3 ) 20987 { 20988 if(0 == gmeList.size()) 20989 { 20990 PRINT_WARNING("No active geometry engine.\n"); 20991 return NULL; 20992 } 20993 20994 GeometryModifyEngine *GMEPtr = get_engine( v1->get_point_ptr() ); 20995 20996 if( GMEPtr != get_engine( v3->get_point_ptr() ) ) 20997 { 20998 PRINT_INFO("Vertices are not from same modeling engine.\n"); 20999 return NULL; 21000 } 21001 21002 TBPoint *pt1, *pt3; 21003 21004 DLIList<RefVertex*> free_ref_vertices; 21005 if( v1->num_parent_ref_entities() == 0 ) 21006 { 21007 free_ref_vertices.append( v1 ); 21008 pt1 = v1->get_point_ptr(); 21009 } 21010 else 21011 pt1 = GMEPtr->make_Point( v1->coordinates() ); 21012 21013 if( v3->num_parent_ref_entities() == 0 ) 21014 { 21015 free_ref_vertices.append( v3 ); 21016 pt3 = v3->get_point_ptr(); 21017 } 21018 else 21019 pt3 = GMEPtr->make_Point( v3->coordinates() ); 21020 21021 21022 if( CubitUndo::get_undo_enabled() ) 21023 { 21024 if( free_ref_vertices.size() ) 21025 CubitUndo::save_state_with_cubit_file( free_ref_vertices, true ); 21026 else 21027 CubitUndo::save_state(); 21028 } 21029 21030 BodySM *sheet_body_sm = NULL; 21031 CubitStatus status = GMEPtr->create_circle_surface(pt1, v2->coordinates(), pt3, sheet_body_sm ); 21032 21033 if( status == CUBIT_FAILURE ) 21034 { 21035 if(CubitUndo::get_undo_enabled()) 21036 CubitUndo::remove_last_undo(); 21037 return NULL; 21038 } 21039 21040 Body *new_body = NULL; 21041 if( sheet_body_sm ) 21042 new_body = GeometryQueryTool::instance()->make_Body(sheet_body_sm); 21043 21044 if (new_body) 21045 { 21046 if(CubitUndo::get_undo_enabled()) 21047 CubitUndo::note_result_body(new_body); 21048 } 21049 else 21050 { 21051 if(CubitUndo::get_undo_enabled()) 21052 CubitUndo::remove_last_undo(); 21053 } 21054 21055 return new_body; 21056 } 21057 21058 Body* GeometryModifyTool::create_circle_surface( RefVertex *v1, 21059 RefVertex *v2, 21060 CubitVector center_point ) 21061 { 21062 if(0 == gmeList.size()) 21063 { 21064 PRINT_WARNING("No active geometry engine.\n"); 21065 return NULL; 21066 } 21067 21068 GeometryModifyEngine *GMEPtr = get_engine( v1->get_point_ptr() ); 21069 21070 if( GMEPtr != get_engine( v2->get_point_ptr() ) ) 21071 { 21072 PRINT_INFO("Vertices are not from same modeling engine.\n"); 21073 return NULL; 21074 } 21075 21076 TBPoint *pt1, *pt2; 21077 21078 DLIList<RefVertex*> free_ref_vertices; 21079 if( v1->num_parent_ref_entities() == 0 ) 21080 { 21081 free_ref_vertices.append( v1 ); 21082 pt1 = v1->get_point_ptr(); 21083 } 21084 else 21085 pt1 = GMEPtr->make_Point( v1->coordinates() ); 21086 21087 if( v2->num_parent_ref_entities() == 0 ) 21088 { 21089 free_ref_vertices.append( v2 ); 21090 pt2 = v2->get_point_ptr(); 21091 } 21092 else 21093 pt2 = GMEPtr->make_Point( v2->coordinates() ); 21094 21095 21096 if( CubitUndo::get_undo_enabled() ) 21097 { 21098 if( free_ref_vertices.size() ) 21099 CubitUndo::save_state_with_cubit_file( free_ref_vertices, true ); 21100 else 21101 CubitUndo::save_state(); 21102 } 21103 21104 BodySM *sheet_body_sm = NULL; 21105 CubitStatus status = GMEPtr->create_circle_surface(pt1, pt2, center_point, sheet_body_sm ); 21106 21107 if( status == CUBIT_FAILURE ) 21108 { 21109 if(CubitUndo::get_undo_enabled()) 21110 CubitUndo::remove_last_undo(); 21111 return NULL; 21112 } 21113 21114 Body *new_body = NULL; 21115 if( sheet_body_sm ) 21116 new_body = GeometryQueryTool::instance()->make_Body(sheet_body_sm); 21117 21118 if (new_body) 21119 { 21120 if(CubitUndo::get_undo_enabled()) 21121 CubitUndo::note_result_body(new_body); 21122 } 21123 else 21124 { 21125 if(CubitUndo::get_undo_enabled()) 21126 CubitUndo::remove_last_undo(); 21127 } 21128 21129 return new_body; 21130 } 21131 21132 Body* GeometryModifyTool::create_ellipse_surface( RefVertex *v1, 21133 RefVertex *v2, 21134 CubitVector center_point ) 21135 { 21136 if(0 == gmeList.size()) 21137 { 21138 PRINT_WARNING("No active geometry engine.\n"); 21139 return NULL; 21140 } 21141 21142 GeometryModifyEngine *GMEPtr = get_engine( v1->get_point_ptr() ); 21143 21144 if( GMEPtr != get_engine( v2->get_point_ptr() ) ) 21145 { 21146 PRINT_INFO("Vertices are not from same modeling engine.\n"); 21147 return NULL; 21148 } 21149 21150 TBPoint *pt1, *pt2; 21151 21152 DLIList<RefVertex*> free_ref_vertices; 21153 if( v1->num_parent_ref_entities() == 0 ) 21154 { 21155 free_ref_vertices.append( v1 ); 21156 pt1 = v1->get_point_ptr(); 21157 } 21158 else 21159 pt1 = GMEPtr->make_Point( v1->coordinates() ); 21160 21161 if( v2->num_parent_ref_entities() == 0 ) 21162 { 21163 free_ref_vertices.append( v2 ); 21164 pt2 = v2->get_point_ptr(); 21165 } 21166 else 21167 pt2 = GMEPtr->make_Point( v2->coordinates() ); 21168 21169 if( CubitUndo::get_undo_enabled() ) 21170 { 21171 if( free_ref_vertices.size() ) 21172 CubitUndo::save_state_with_cubit_file( free_ref_vertices, true ); 21173 else 21174 CubitUndo::save_state(); 21175 } 21176 21177 BodySM *sheet_body_sm = NULL; 21178 CubitStatus status = GMEPtr->create_ellipse_surface(pt1, pt2, center_point, sheet_body_sm ); 21179 21180 if( status == CUBIT_FAILURE ) 21181 { 21182 if(CubitUndo::get_undo_enabled()) 21183 CubitUndo::remove_last_undo(); 21184 return NULL; 21185 } 21186 21187 Body *new_body = NULL; 21188 if( sheet_body_sm ) 21189 new_body = GeometryQueryTool::instance()->make_Body(sheet_body_sm); 21190 21191 if (new_body) 21192 { 21193 if(CubitUndo::get_undo_enabled()) 21194 CubitUndo::note_result_body(new_body); 21195 } 21196 else 21197 { 21198 if(CubitUndo::get_undo_enabled()) 21199 CubitUndo::remove_last_undo(); 21200 } 21201 21202 return new_body; 21203 } 21204 21205 Body* GeometryModifyTool::create_ellipse_surface( double major_radius, 21206 double minor_radius, 21207 CubitVector plane ) 21208 { 21209 if(0 == gmeList.size()) 21210 { 21211 PRINT_WARNING("No active geometry engine.\n"); 21212 return NULL; 21213 } 21214 21215 if( major_radius <= GEOMETRY_RESABS || minor_radius <= GEOMETRY_RESABS ) 21216 { 21217 PRINT_ERROR("Values must be positive\n"); 21218 return NULL; 21219 } 21220 21221 if( CubitUndo::get_undo_enabled() ) 21222 CubitUndo::save_state(); 21223 21224 BodySM *sheet_body_sm = NULL; 21225 CubitStatus status = gmeList.get()->create_ellipse_surface(major_radius, minor_radius, plane, sheet_body_sm ); 21226 21227 if( status == CUBIT_FAILURE ) 21228 { 21229 if(CubitUndo::get_undo_enabled()) 21230 CubitUndo::remove_last_undo(); 21231 return NULL; 21232 } 21233 21234 Body *new_body = NULL; 21235 if( sheet_body_sm ) 21236 new_body = GeometryQueryTool::instance()->make_Body(sheet_body_sm); 21237 21238 if (new_body) 21239 { 21240 if(CubitUndo::get_undo_enabled()) 21241 CubitUndo::note_result_body(new_body); 21242 } 21243 else 21244 { 21245 if(CubitUndo::get_undo_enabled()) 21246 CubitUndo::remove_last_undo(); 21247 } 21248 21249 return new_body; 21250 } 21251 21252 CubitStatus GeometryModifyTool::create_curve_helix( CubitVector &location, 21253 CubitVector &direction, 21254 CubitVector &start_point, 21255 double &thread_distance, 21256 double &angle, 21257 bool right_handed, 21258 RefEdge *&new_ref_edge_ptr) 21259 { 21260 if (0 == gmeList.size()) 21261 { 21262 PRINT_WARNING("No active geometry engine.\n"); 21263 return CUBIT_FAILURE; 21264 } 21265 21266 Curve *new_curve = gmeList.get()->create_curve_helix(location, direction, 21267 start_point, thread_distance, 21268 angle, right_handed ); 21269 21270 if (new_curve == NULL) 21271 return CUBIT_FAILURE; 21272 21273 if( CubitUndo::get_undo_enabled() ) 21274 CubitUndo::save_state(); 21275 21276 new_ref_edge_ptr = GeometryQueryTool::instance()->make_free_RefEdge(new_curve); 21277 21278 if( CubitUndo::get_undo_enabled() ) 21279 CubitUndo::note_result_entity( new_ref_edge_ptr ); 21280 21281 return CUBIT_SUCCESS; 21282 } 21283 21284 void GeometryModifyTool::remove_bodies_outside_bounding_box( 21285 DLIList<Body*> &body_list, 21286 CubitBox &tool_bounding_box ) 21287 { 21288 //remove bodies that don't overlap 21289 for( int k=body_list.size(); k--; ) 21290 { 21291 Body *tmp_body = body_list.get(); 21292 if( !tool_bounding_box.overlap( 0.001, tmp_body->bounding_box() ) ) 21293 body_list.change_to( NULL ); 21294 body_list.step(); 21295 } 21296 21297 body_list.remove_all_with_value(NULL); 21298 } 21299 21300 21301 21302 void GeometryModifyTool::remove_bodies_outside_bounding_box( 21303 DLIList<Body*> &body_list, 21304 CubitVector v1, CubitVector v2, CubitVector v3 ) 21305 { 21306 //create a bounding box from the body list and the passed in points 21307 CubitBox bbox1; 21308 for( int k=body_list.size(); k--; ) 21309 bbox1 |= body_list.get_and_step()->bounding_box(); 21310 21311 //add in the pts 21312 bbox1 |= v1; 21313 bbox1 |= v2; 21314 bbox1 |= v3; 21315 21316 //get the diagonal of the bounding box 21317 double diagonal_length = bbox1.diagonal().length(); 21318 21319 //offset each point by the diagonal 21320 CubitVector new_pt; 21321 CubitVector direction; 21322 direction = v2-v1; 21323 direction.normalize(); 21324 new_pt = v1 + direction*diagonal_length; 21325 21326 CubitBox bbox2( new_pt ); 21327 21328 direction = v3-v1; 21329 direction.normalize(); 21330 new_pt = v1 + direction*diagonal_length; 21331 bbox2 |= new_pt; 21332 21333 direction = v1-v2; 21334 direction.normalize(); 21335 new_pt = v2 + direction*diagonal_length; 21336 bbox2 |= new_pt; 21337 direction = v3-v2; 21338 direction.normalize(); 21339 new_pt = v2 + direction*diagonal_length; 21340 bbox2 |= new_pt; 21341 21342 direction = v1-v3; 21343 direction.normalize(); 21344 new_pt = v3 + direction*diagonal_length; 21345 bbox2 |= new_pt; 21346 direction = v2-v3; 21347 direction.normalize(); 21348 new_pt = v3 + direction*diagonal_length; 21349 bbox2 |= new_pt; 21350 21351 //remove bodies that don't overlap 21352 for( int k=body_list.size(); k--; ) 21353 { 21354 Body *tmp_body = body_list.get(); 21355 if( !bbox2.overlap( 0.001, tmp_body->bounding_box() ) ) 21356 body_list.change_to( NULL ); 21357 body_list.step(); 21358 } 21359 21360 body_list.remove_all_with_value(NULL); 21361 } 21362 21363 CubitStatus prepare_surface_sweep( 21364 DLIList<BodySM*> &blank_bodies, 21365 DLIList<Surface*> &surfaces, 21366 const CubitVector& sweep_vector, 21367 bool sweep_perp, 21368 bool through_all, 21369 bool outward, 21370 bool up_to_next, 21371 Surface *stop_surf, 21372 Curve *curve_to_sweep_along, 21373 BodySM* &cutting_tool_ptr , 21374 const CubitVector* point , 21375 double *angle ) 21376 { 21377 GeometryModifyEngine* gme = GeometryModifyTool::instance()-> 21378 get_engine(blank_bodies.get()); 21379 21380 if(surfaces.size() == 0 ) 21381 return CUBIT_FAILURE; 21382 21383 DLIList<GeometryEntity*> ref_ent_list; 21384 Surface * temp_face = NULL; 21385 for(int i = 0; i < surfaces.size(); i++) 21386 { 21387 //copy the faces before sweep 21388 temp_face = gme->make_Surface(surfaces.get_and_step()); 21389 if (temp_face) 21390 ref_ent_list.append((GeometryEntity*)temp_face); 21391 } 21392 21393 BodySM* to_body = NULL; 21394 CubitStatus stat = CUBIT_SUCCESS; 21395 if(up_to_next && blank_bodies.size() > 1) //unite all bland_bodies 21396 { 21397 DLIList<BodySM*> newBodies; 21398 DLIList<BodySM*> copied_bodies; 21399 for(int i = 0; i < blank_bodies.size(); i++) 21400 copied_bodies.append(gme->copy_body(blank_bodies.get_and_step())); 21401 21402 stat = gme->unite(copied_bodies, newBodies); 21403 if(stat == CUBIT_FAILURE) 21404 { 21405 PRINT_ERROR("Cannot use 'up_to_next' option with specified geometry\n"); 21406 PRINT_INFO("Try the 'stop surface <id>' option instead\n"); 21407 return stat; 21408 } 21409 to_body = newBodies.get(); 21410 } 21411 21412 else if(up_to_next && blank_bodies.size() == 1) 21413 to_body = gme->copy_body(blank_bodies.get()); 21414 21415 DLIList<BodySM*> swept_bodies; 21416 if (point && angle) //sweep_surface_rotated 21417 stat = gme->sweep_rotational(ref_ent_list,swept_bodies,*point, 21418 sweep_vector, *angle,0, 0.0,0,false,false, 21419 false,stop_surf, to_body); 21420 21421 else 21422 { 21423 CubitVector tmp_sweep_vector = sweep_vector; 21424 21425 //get model bbox info...will scale sweep vector by its diagonal 21426 //so that we go far enough 21427 if( through_all || stop_surf || up_to_next) 21428 { 21429 CubitBox bounding_box = GeometryQueryTool::instance()->model_bounding_box(); 21430 tmp_sweep_vector.normalize(); 21431 tmp_sweep_vector*=(2*bounding_box.diagonal().length()); 21432 } 21433 21434 //see if we're sweeping along a specified curve 21435 if( curve_to_sweep_along ) 21436 { 21437 DLIList<Curve*> curves_to_sweep_along; 21438 curves_to_sweep_along.append(curve_to_sweep_along); 21439 stat = gme->sweep_along_curve(ref_ent_list, swept_bodies, 21440 curves_to_sweep_along, 0.0,0,false,stop_surf, 21441 to_body); 21442 } 21443 21444 else if (sweep_perp ) 21445 stat = gme->sweep_perpendicular(ref_ent_list, swept_bodies, 21446 tmp_sweep_vector.length(),0.0,0,!outward,false, 21447 stop_surf, to_body); 21448 else 21449 stat = gme->sweep_translational(ref_ent_list, swept_bodies, 21450 tmp_sweep_vector,0.0,0, false, false, stop_surf, 21451 to_body); 21452 } 21453 21454 if(stat == CUBIT_FAILURE || swept_bodies.size() == 0) 21455 { 21456 //delete copied faces 21457 GeometryEntity * temp_entity = NULL; 21458 for(int i = ref_ent_list.size();i--;) 21459 { 21460 temp_entity = ref_ent_list.get_and_step(); 21461 if (temp_entity) 21462 gme->get_gqe()->delete_solid_model_entities( (Surface*)temp_entity); 21463 } 21464 21465 return stat; 21466 } 21467 21468 //if there are more than 1, unite them all 21469 DLIList<BodySM*> newBodies; 21470 if (swept_bodies.size() > 1) 21471 stat = gme->unite(swept_bodies, newBodies); 21472 else 21473 newBodies = swept_bodies; 21474 21475 if(stat == CUBIT_FAILURE || newBodies.size()!= 1) 21476 { 21477 PRINT_ERROR("webcut tool body is not created from occ.\n"); 21478 //delete the swept_bodies 21479 BodySM* tmp_body = NULL; 21480 for (int i = swept_bodies.size(); i--;) 21481 { 21482 tmp_body= swept_bodies.get_and_step(); 21483 if (tmp_body) 21484 gme->get_gqe()->delete_solid_model_entities(tmp_body); 21485 } 21486 21487 //delete copied faces 21488 GeometryEntity * temp_entity = NULL; 21489 for(int i = ref_ent_list.size();i--;) 21490 { 21491 temp_entity = ref_ent_list.get_and_step(); 21492 if (temp_entity) 21493 gme->get_gqe()->delete_solid_model_entities( (Surface*)temp_entity); 21494 } 21495 return CUBIT_FAILURE; 21496 } 21497 21498 cutting_tool_ptr = newBodies.get(); 21499 return stat; 21500 } 21501 21502 21503 21504 //****************************************************************************************************************************** 21505 CubitVector GeometryModifyTool::FindExtendedEndPt( double outer_rad , double inner_rad , CubitVector inner_AxisPt , 21506 CubitVector Axis , double Height ) 21507 { 21508 CubitVector Extended_End_Pt; 21509 21510 double Diff = (outer_rad - inner_rad); 21511 Diff /= Height; 21512 double dAngle = atan ( Diff ) ; 21513 Axis.normalize(); 21514 21515 double dTan = tan( dAngle ); 21516 double dExtendvalue = inner_rad / dTan; 21517 21518 CubitVector ExtendedPt; 21519 ExtendedPt.x( ( Axis.x() * dExtendvalue ) + inner_AxisPt.x() ); 21520 ExtendedPt.y( ( Axis.y() * dExtendvalue ) + inner_AxisPt.y() ); 21521 ExtendedPt.z( ( Axis.z() * dExtendvalue ) + inner_AxisPt.z() ); 21522 21523 return ExtendedPt; 21524 } 21525 //********************************************************************************************************************************** 21526 CubitVector GeometryModifyTool::FindExtendedStartPt( CubitBox Box , double outer_rad , double inner_rad , CubitVector AxisPt , 21527 CubitVector Axis , double &dLength , double dTanAngle, double &dExtendedadius ) 21528 { 21529 CubitVector Extended_Start_Pt; 21530 21531 // Find the Difference between the Max and thre min values in all 3 directions. 21532 // Incase the point is within the box limits, then add the difference values 21533 // in all 3 directions , witht he " Axis " as the direction vector and extend the point. 21534 21535 // After that find the Radius of this bigger end. 21536 21537 CubitVector DiffVec; 21538 21539 Axis.normalize(); 21540 21541 DiffVec.x( fabs( Box.max_x() - Box.min_x() )); 21542 DiffVec.y( fabs( Box.max_y() - Box.min_y() )); 21543 DiffVec.z( fabs( Box.max_z() - Box.min_z() )); 21544 21545 // Extend the start Pt 21546 21547 Extended_Start_Pt.x( AxisPt.x() + ( Axis.x() * DiffVec.x() ) ); 21548 Extended_Start_Pt.y( AxisPt.y() + ( Axis.y() * DiffVec.y() ) ); 21549 Extended_Start_Pt.z( AxisPt.z() + ( Axis.z() * DiffVec.z() ) ); 21550 21551 21552 // Find the length 21553 21554 dLength = sqrt( (( AxisPt.x() - Extended_Start_Pt.x()) * (AxisPt.x() - Extended_Start_Pt.x()) ) + 21555 (( AxisPt.y() - Extended_Start_Pt.y()) * (AxisPt.y() - Extended_Start_Pt.y()) ) + 21556 (( AxisPt.z() - Extended_Start_Pt.z()) * (AxisPt.z() - Extended_Start_Pt.z()) ) ); 21557 21558 21559 21560 // Find the Extended Radius 21561 21562 dExtendedadius = outer_rad + ( tan( dTanAngle ) * dLength ) ; 21563 21564 return Extended_Start_Pt; 21565 } 21566 //***************************************************************************************************************************************** 21567 void GeometryModifyTool::FindExtendedPoints( CubitVector AxisPt1 , CubitVector AxisPt2 , double outer_radius , double inner_radius , 21568 CubitVector axis,double Height , CubitBox bounding_box , double dTanAngle , 21569 CubitVector& start , CubitVector& end , double& dExtended_OuterRadius, double& dExtended_InnerRadius ) 21570 { 21571 21572 CubitVector endpt ; 21573 if( outer_radius > inner_radius ) 21574 { 21575 endpt = FindExtendedEndPt( outer_radius , inner_radius , AxisPt2 , axis, Height ); 21576 Height = sqrt( (endpt.x() - AxisPt1.x()) * (endpt.x() - AxisPt1.x())+ 21577 (endpt.y() - AxisPt1.y()) * (endpt.y() - AxisPt1.y())+ 21578 (endpt.z() - AxisPt1.z()) * (endpt.z() - AxisPt1.z()) ); 21579 21580 AxisPt2.x( endpt.x() ); 21581 AxisPt2.y( endpt.y() ); 21582 AxisPt2.z( endpt.z() ); 21583 21584 end.x( endpt.x() ); 21585 end.y( endpt.y() ); 21586 end.z( endpt.z() ); 21587 21588 dExtended_InnerRadius = 0; 21589 } 21590 else 21591 { 21592 // reverse the axis. 21593 21594 axis.x( -axis.x()); 21595 axis.y( -axis.y()); 21596 axis.z( -axis.z()); 21597 21598 endpt = FindExtendedEndPt( inner_radius , outer_radius , AxisPt1 , axis, Height ); 21599 Height = sqrt( (endpt.x() - AxisPt2.x()) * (endpt.x() - AxisPt2.x())+ 21600 (endpt.y() - AxisPt2.y()) * (endpt.y() - AxisPt2.y())+ 21601 (endpt.z() - AxisPt2.z()) * (endpt.z() - AxisPt2.z()) ); 21602 21603 AxisPt1.x( endpt.x() ); 21604 AxisPt1.y( endpt.y() ); 21605 AxisPt1.z( endpt.z() ); 21606 21607 start.x( endpt.x() ); 21608 start.y( endpt.y() ); 21609 start.z( endpt.z() ); 21610 21611 // reset the axis. 21612 axis.x( -axis.x()); 21613 axis.y( -axis.y()); 21614 axis.z( -axis.z()); 21615 21616 21617 dExtended_OuterRadius = 0; 21618 21619 } 21620 21621 21622 21623 //*****************************************// 21624 // Now find the extension of the bigger end. 21625 //*****************************************// 21626 21627 if( outer_radius > inner_radius ) 21628 { 21629 // reverse the axis. 21630 axis.x( -axis.x()); 21631 axis.y( -axis.y()); 21632 axis.z( -axis.z()); 21633 21634 21635 endpt = FindExtendedStartPt( bounding_box , outer_radius , inner_radius , AxisPt1 , axis, Height , dTanAngle , dExtended_OuterRadius ); 21636 Height = sqrt( (endpt.x() - AxisPt2.x()) * (endpt.x() - AxisPt2.x())+ 21637 (endpt.y() - AxisPt2.y()) * (endpt.y() - AxisPt2.y())+ 21638 (endpt.z() - AxisPt2.z()) * (endpt.z() - AxisPt2.z()) ); 21639 21640 AxisPt1.x( endpt.x() ); 21641 AxisPt1.y( endpt.y() ); 21642 AxisPt1.z( endpt.z() ); 21643 21644 start.x( endpt.x() ); 21645 start.y( endpt.y() ); 21646 start.z( endpt.z() ); 21647 21648 // reverse the axis. 21649 axis.x( -axis.x()); 21650 axis.y( -axis.y()); 21651 axis.z( -axis.z()); 21652 21653 } 21654 else 21655 { 21656 endpt = FindExtendedStartPt( bounding_box , inner_radius , outer_radius , AxisPt2 , axis, Height , dTanAngle , dExtended_InnerRadius ); 21657 Height = sqrt( (endpt.x() - AxisPt1.x()) * (endpt.x() - AxisPt1.x())+ 21658 (endpt.y() - AxisPt1.y()) * (endpt.y() - AxisPt1.y())+ 21659 (endpt.z() - AxisPt1.z()) * (endpt.z() - AxisPt1.z()) ); 21660 21661 AxisPt2.x( endpt.x() ); 21662 AxisPt2.y( endpt.y() ); 21663 AxisPt2.z( endpt.z() ); 21664 21665 end.x( endpt.x() ); 21666 end.y( endpt.y() ); 21667 end.z( endpt.z() ); 21668 } 21669 } 21670 21671 //This function gets called after RefEntities have been created 21672 //on TopologyBridges. It builds up a map from original RefEntity 21673 //to the copy RefEntity. Used when copying Bodies, RefFaces, and 21674 //RefEdges. 21675 CubitStatus GeometryModifyTool::create_old_to_new_ref_ent_map( 21676 TopologyBridge *old_top_level_bridge, 21677 TopologyBridge *new_top_level_bridge, 21678 std::map< RefEntity*, RefEntity* > &old_to_new_map, 21679 std::map< TopologyBridge*, TopologyBridge*> &old_tb_to_new_tb ) 21680 { 21681 std::vector< std::pair<TopologyBridge*, TopologyBridge*> > unmatched_pairs; 21682 bool debug = false; 21683 std::map< TopologyBridge*, TopologyBridge*>::iterator iter; 21684 21685 //This first loop tries to find a RefEntity on each TopologyBridge pair in the 21686 //map 'old_tb_to_new_tb'. If there is no virtual geometry here, everything 21687 //should be found. If it didn't find a RefEntity, put it in the 21688 //unmatched_pairs vector. 21689 for( iter = old_tb_to_new_tb.begin(); iter!=old_tb_to_new_tb.end(); iter++ ) 21690 { 21691 std::pair<TopologyBridge*, TopologyBridge*> tmp_pair = *iter; 21692 TopologyBridge *old_tb = tmp_pair.first; 21693 TopologyBridge *new_tb = tmp_pair.second; 21694 21695 TopologyEntity *te_old = old_tb->topology_entity(); 21696 TopologyEntity *te_new = new_tb->topology_entity(); 21697 21698 if( te_old && te_new ) 21699 { 21700 RefEntity *old_ref_ent = dynamic_cast<RefEntity*>(te_old); 21701 RefEntity *new_ref_ent = dynamic_cast<RefEntity*>(te_new); 21702 21703 if( old_ref_ent && new_ref_ent ) 21704 { 21705 if( debug ) 21706 PRINT_INFO("%s %d ---> %s %d\n", 21707 old_ref_ent->class_name(), old_ref_ent->id(), 21708 new_ref_ent->class_name(), new_ref_ent->id() ); 21709 21710 old_to_new_map.insert( std::make_pair( old_ref_ent, new_ref_ent ) ); 21711 } 21712 else 21713 unmatched_pairs.push_back( tmp_pair ); 21714 } 21715 else 21716 unmatched_pairs.push_back( tmp_pair ); 21717 } 21718 21719 //Virtual geometry will be in unmatched pairs. Composite will have an n-to-1 21720 //TB-to-RefEntity mapping. So it might try to stuff duplicate pairs into the 21721 //map, but that's alright. 21722 for( size_t k=0; k<unmatched_pairs.size(); k++ ) 21723 { 21724 std::pair<TopologyBridge*, TopologyBridge*> tmp_pair = unmatched_pairs[k]; 21725 21726 TopologyBridge *old_tb = tmp_pair.first; 21727 TopologyBridge *new_tb = tmp_pair.second; 21728 21729 //get the owner tbs associate with old_tb 21730 DLIList<TopologyBridge*> old_owner_tbs; 21731 GeometryQueryTool::instance()->get_tbs_with_bridge_manager_as_owner( old_tb, old_owner_tbs ); 21732 21733 DLIList<TopologyBridge*> new_owner_tbs; 21734 GeometryQueryTool::instance()->get_tbs_with_bridge_manager_as_owner( new_tb, new_owner_tbs ); 21735 21736 if( old_owner_tbs.size() && old_owner_tbs.size() == new_owner_tbs.size() ) 21737 { 21738 if( old_owner_tbs.size() == 1 && new_owner_tbs.size() == 1 ) //composite case 21739 { 21740 TopologyEntity *te_old = old_owner_tbs.get()->topology_entity(); 21741 TopologyEntity *te_new = new_owner_tbs.get()->topology_entity(); 21742 21743 if( te_old && te_new ) 21744 { 21745 RefEntity *old_ref_ent = dynamic_cast<RefEntity*>(te_old); 21746 RefEntity *new_ref_ent = dynamic_cast<RefEntity*>(te_new); 21747 21748 if( old_ref_ent && new_ref_ent ) 21749 { 21750 if( debug ) 21751 PRINT_INFO("Virtual: %s %d ---> %s %d\n", 21752 old_ref_ent->class_name(), old_ref_ent->id(), 21753 new_ref_ent->class_name(), new_ref_ent->id() ); 21754 21755 old_to_new_map.insert( std::make_pair( old_ref_ent, new_ref_ent ) ); 21756 21757 old_tb_to_new_tb.insert( std::make_pair( old_owner_tbs.get(), new_owner_tbs.get() ) ); 21758 } 21759 } 21760 } 21761 } 21762 } 21763 21764 //Partitions can hide entities because of the the n-to-m mapping. 21765 //The solution is to get all the child TB lumps, surface, curves, and 21766 //points. 21767 double tol_sq = old_top_level_bridge->get_geometry_query_engine()->get_sme_resabs_tolerance(); 21768 tol_sq *= tol_sq; 21769 21770 DLIList<Lump*> old_lumps, new_lumps; 21771 DLIList<Surface*> old_surfaces, new_surfaces; 21772 DLIList<Curve*> old_curves, new_curves; 21773 DLIList<TBPoint*> old_points, new_points; 21774 21775 if( dynamic_cast<BodySM*>(old_top_level_bridge) ) 21776 { 21777 old_top_level_bridge->lumps( old_lumps ); 21778 old_top_level_bridge->surfaces( old_surfaces ); 21779 new_top_level_bridge->lumps( new_lumps ); 21780 new_top_level_bridge->surfaces( new_surfaces ); 21781 } 21782 21783 old_top_level_bridge->curves( old_curves ); 21784 old_top_level_bridge->points( old_points ); 21785 new_top_level_bridge->curves( new_curves ); 21786 new_top_level_bridge->points( new_points ); 21787 21788 //If it is already in the map, it has been paired to something. 21789 //Remove it from the list and forget about it. 21790 for( int k=0; k<old_lumps.size(); k++ ) 21791 { 21792 //if it is found, make it NULL in the list 21793 iter = old_tb_to_new_tb.find( old_lumps[k] ); 21794 if( iter != old_tb_to_new_tb.end() ) 21795 { 21796 old_lumps[k] = NULL; 21797 if( new_lumps.move_to( (Lump*)iter->second ) ) 21798 new_lumps.change_to( NULL ); 21799 } 21800 } 21801 for( int k=0; k<old_surfaces.size(); k++ ) 21802 { 21803 //if it is found, make it NULL in the list 21804 iter = old_tb_to_new_tb.find( old_surfaces[k] ); 21805 if( iter != old_tb_to_new_tb.end() ) 21806 { 21807 old_surfaces[k] = NULL; 21808 if( new_surfaces.move_to( (Surface*)iter->second ) ) 21809 new_surfaces.change_to( NULL ); 21810 } 21811 } 21812 for( int k=0; k<old_curves.size(); k++ ) 21813 { 21814 //if it is found, make it NULL in the list 21815 iter = old_tb_to_new_tb.find( old_curves[k] ); 21816 if( iter != old_tb_to_new_tb.end() ) 21817 { 21818 old_curves[k] = NULL; 21819 if( new_curves.move_to( (Curve*)iter->second ) ) 21820 new_curves.change_to( NULL ); 21821 } 21822 } 21823 for( int k=0; k<old_points.size(); k++ ) 21824 { 21825 //if it is found, make it NULL in the list 21826 iter = old_tb_to_new_tb.find( old_points[k] ); 21827 if( iter != old_tb_to_new_tb.end() ) 21828 { 21829 old_points[k] = NULL; 21830 if( new_points.move_to( (TBPoint*)iter->second ) ) 21831 new_points.change_to( NULL ); 21832 } 21833 } 21834 21835 //Remove all the NULL-ed out stuff 21836 old_lumps.remove_all_with_value(NULL); 21837 old_surfaces.remove_all_with_value(NULL); 21838 old_curves.remove_all_with_value(NULL); 21839 old_points.remove_all_with_value(NULL); 21840 21841 new_lumps.remove_all_with_value(NULL); 21842 new_surfaces.remove_all_with_value(NULL); 21843 new_curves.remove_all_with_value(NULL); 21844 new_points.remove_all_with_value(NULL); 21845 21846 //should have exact correspondence 21847 if( old_lumps.size() != new_lumps.size() ) 21848 return CUBIT_FAILURE; 21849 if( old_surfaces.size() != new_surfaces.size() ) 21850 return CUBIT_FAILURE; 21851 if( old_curves.size() != new_curves.size() ) 21852 return CUBIT_FAILURE; 21853 if( old_points.size() != new_points.size() ) 21854 return CUBIT_FAILURE; 21855 21856 //If we are here, there are partitions we have to resolve. The only way to do it 21857 //is a brute force approach. It's save to use a tolerance since we know the 21858 //entities will be exactly on top of each other. 21859 for( int k=0; k<old_surfaces.size(); k++ ) 21860 { 21861 Surface *old_surf = old_surfaces[k]; 21862 CubitBox old_bbox = old_surf->bounding_box(); 21863 21864 for( int j=0; j<new_surfaces.size(); j++ ) 21865 { 21866 Surface *new_surf = new_surfaces[j]; 21867 if( new_surf ) 21868 { 21869 CubitBox new_bbox = new_surf->bounding_box(); 21870 if( old_bbox.center().distance_between_squared( new_bbox.center() ) < tol_sq ) 21871 { 21872 if( fabs(old_bbox.diagonal().length_squared() - 21873 new_bbox.diagonal().length_squared() ) < tol_sq ) 21874 { 21875 TopologyEntity *te_old = old_surf->topology_entity(); 21876 TopologyEntity *te_new = new_surf->topology_entity(); 21877 21878 if( te_old && te_new ) 21879 { 21880 RefEntity *old_ref_ent = dynamic_cast<RefEntity*>(te_old); 21881 RefEntity *new_ref_ent = dynamic_cast<RefEntity*>(te_new); 21882 21883 if( old_ref_ent && new_ref_ent ) 21884 { 21885 if( debug ) 21886 PRINT_INFO("Partition: %s %d ---> %s %d\n", 21887 old_ref_ent->class_name(), old_ref_ent->id(), 21888 new_ref_ent->class_name(), new_ref_ent->id() ); 21889 21890 old_to_new_map.insert( std::make_pair( old_ref_ent, new_ref_ent ) ); 21891 new_surfaces[j] = NULL; 21892 break; 21893 } 21894 } 21895 } 21896 } 21897 } 21898 } 21899 } 21900 21901 //Curves 21902 for( int k=0; k<old_curves.size(); k++ ) 21903 { 21904 Curve *old_curve = old_curves[k]; 21905 CubitBox old_bbox = old_curve->bounding_box(); 21906 21907 for( int j=0; j<new_curves.size(); j++ ) 21908 { 21909 Curve *new_curve = new_curves[j]; 21910 if( new_curve ) 21911 { 21912 CubitBox new_bbox = new_curve->bounding_box(); 21913 if( old_bbox.center().distance_between_squared( new_bbox.center() ) < tol_sq ) 21914 { 21915 if( fabs(old_bbox.diagonal().length_squared() - 21916 new_bbox.diagonal().length_squared() ) < tol_sq ) 21917 { 21918 TopologyEntity *te_old = old_curve->topology_entity(); 21919 TopologyEntity *te_new = new_curve->topology_entity(); 21920 21921 if( te_old && te_new ) 21922 { 21923 RefEntity *old_ref_ent = dynamic_cast<RefEntity*>(te_old); 21924 RefEntity *new_ref_ent = dynamic_cast<RefEntity*>(te_new); 21925 21926 if( old_ref_ent && new_ref_ent ) 21927 { 21928 if( debug ) 21929 PRINT_INFO("Partition: %s %d ---> %s %d\n", 21930 old_ref_ent->class_name(), old_ref_ent->id(), 21931 new_ref_ent->class_name(), new_ref_ent->id() ); 21932 21933 old_to_new_map.insert( std::make_pair( old_ref_ent, new_ref_ent ) ); 21934 new_curves[j] = NULL; 21935 break; 21936 } 21937 } 21938 } 21939 } 21940 } 21941 } 21942 } 21943 21944 //Points 21945 for( int k=0; k<old_points.size(); k++ ) 21946 { 21947 TBPoint *old_point = old_points[k]; 21948 CubitBox old_bbox = old_point->bounding_box(); 21949 21950 for( int j=0; j<new_points.size(); j++ ) 21951 { 21952 TBPoint *new_point = new_points[j]; 21953 if( new_point ) 21954 { 21955 CubitBox new_bbox = new_point->bounding_box(); 21956 if( old_bbox.center().distance_between_squared( new_bbox.center() ) < tol_sq ) 21957 { 21958 if( fabs(old_bbox.diagonal().length_squared() - 21959 new_bbox.diagonal().length_squared() ) < tol_sq ) 21960 { 21961 TopologyEntity *te_old = old_point->topology_entity(); 21962 TopologyEntity *te_new = new_point->topology_entity(); 21963 21964 if( te_old && te_new ) 21965 { 21966 RefEntity *old_ref_ent = dynamic_cast<RefEntity*>(te_old); 21967 RefEntity *new_ref_ent = dynamic_cast<RefEntity*>(te_new); 21968 21969 if( old_ref_ent && new_ref_ent ) 21970 { 21971 if( debug ) 21972 PRINT_INFO("Partition: %s %d ---> %s %d\n", 21973 old_ref_ent->class_name(), old_ref_ent->id(), 21974 new_ref_ent->class_name(), new_ref_ent->id() ); 21975 21976 old_to_new_map.insert( std::make_pair( old_ref_ent, new_ref_ent ) ); 21977 new_points[j] = NULL; 21978 break; 21979 } 21980 } 21981 } 21982 } 21983 } 21984 } 21985 } 21986 21987 return CUBIT_SUCCESS; 21988 21989 } 21990 21991 //author: Jane Hu 21992 //Date Created: Jan. 9, 2013 21993 CubitStatus webcut_w_cylinder( DLIList<BodySM*> &webcut_body_list, 21994 double radius, 21995 const CubitVector &axis, 21996 const CubitVector ¢er, 21997 DLIList<BodySM*>& neighbor_imprint_list, 21998 DLIList<BodySM*>& results_list, 21999 ImprintType imprint_type ) 22000 { 22001 GeometryModifyEngine* gme = 0; 22002 gme = GeometryModifyTool::instance()-> 22003 get_engine(webcut_body_list.get()); 22004 assert(gme); 22005 22006 double max_size = 0.; 22007 //lets find the distance to the center for each body and take 22008 //the max. 22009 double curr; 22010 CubitVector cent_bod; 22011 CubitBox bounding_box; 22012 BodySM *body_ptr; 22013 bounding_box = webcut_body_list[0]->bounding_box(); 22014 cent_bod = bounding_box.center(); 22015 cent_bod = cent_bod - center; 22016 curr = cent_bod.length(); 22017 if ( curr > max_size ) 22018 max_size = curr; 22019 22020 22021 for ( int ii = webcut_body_list.size()-1; ii > 0; ii-- ) 22022 { 22023 body_ptr = webcut_body_list[ii]; 22024 bounding_box |= body_ptr->bounding_box(); 22025 cent_bod = body_ptr->bounding_box().center(); 22026 cent_bod = cent_bod - center; 22027 curr = cent_bod.length(); 22028 if ( curr > max_size ) 22029 max_size = curr; 22030 } 22031 22032 curr = bounding_box.diagonal().length(); 22033 22034 if ( curr > max_size ) 22035 max_size = curr; 22036 22037 double height = 0.0; 22038 if ( center.x() > max_size ) 22039 { 22040 height = 500.0 * center.x(); 22041 } 22042 else if ( center.y() > max_size ) 22043 { 22044 height = 500.0 * center.y(); 22045 } 22046 else if ( center.z() > max_size ) 22047 { 22048 height = 500.0 * center.z(); 22049 } 22050 else 22051 { 22052 height = 500.0 * max_size; 22053 } 22054 22055 //lets make certain we have a valid height.. 22056 if ( height < GEOMETRY_RESABS ) 22057 { 22058 height = 500.0; 22059 } 22060 22061 BodySM *cutting_tool_ptr = gme->cylinder( height, radius, radius, radius ); 22062 22063 if( cutting_tool_ptr == NULL ) 22064 return CUBIT_FAILURE; 22065 22066 //transform the cyclinder to cernter and axis 22067 // The current frustum is centered on the z axis. 22068 CubitVector axis2(0., 0., 1.0 ); 22069 //now find the normal to the current axis and axis we want to be 22070 //at. This normal is where we will rotate about. 22071 CubitVector normal_axis = axis2 * axis; 22072 if ( normal_axis.length() > CUBIT_RESABS ) 22073 { 22074 //angle in degrees. 22075 double angle = normal_axis.vector_angle( axis2, axis ); 22076 gme->get_gqe()->rotate(cutting_tool_ptr, normal_axis, angle); 22077 } 22078 gme->get_gqe()->translate(cutting_tool_ptr, center); 22079 22080 CubitStatus stat = gme->webcut( webcut_body_list, cutting_tool_ptr, 22081 neighbor_imprint_list, results_list, imprint_type) ; 22082 22083 // Delete the BodySM that was created to be used as a tool 22084 gme->get_gqe()->delete_solid_model_entities(cutting_tool_ptr) ; 22085 22086 return stat; 22087 } 22088 22089 //********************************************************************************************************************************************************************* 22090