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 }