cgma
|
00001 //------------------------------------------------------------------------- 00002 //------------------------------------------------------------------------- 00003 00004 // Filename : OCCModifyEngine.cpp 00005 // 00006 // Purpose : ModifyEngine for OCC geometry 00007 // 00008 // Special Notes : Modeled after GeometryModifyEngine 00009 // 00010 // Author : Jane Hu 00011 // 00012 // Creation Date : 1/08 00013 // 00014 //------------------------------------------------------------------------- 00015 #include "gp_Pnt.hxx" 00016 #include "gp_Ax2.hxx" 00017 #include "gp_Dir.hxx" 00018 #include "gp_Hypr.hxx" 00019 #include "gp_Parab.hxx" 00020 #include "gp_Elips.hxx" 00021 #include "gp_Pln.hxx" 00022 #include "gp_Circ.hxx" 00023 #include "gp_Cylinder.hxx" 00024 #include "gp_Cone.hxx" 00025 #include "gp_Sphere.hxx" 00026 #include "gp_Torus.hxx" 00027 #include "BRepOffsetAPI_MakeOffset.hxx" 00028 #include "BRepBuilderAPI_MakeShell.hxx" 00029 #include "BRepBuilderAPI_MakeSolid.hxx" 00030 #include "BRepOffsetAPI_MakeDraft.hxx" 00031 #include "BRepBuilderAPI_TransitionMode.hxx" 00032 #include "BRepBuilderAPI_MakeWire.hxx" 00033 #include "BRepPrimAPI_MakeHalfSpace.hxx" 00034 #include "BRepBuilderAPI_MakePolygon.hxx" 00035 #include "BRepBuilderAPI_Sewing.hxx" 00036 #include "BRepBndLib.hxx" 00037 #include "IntersectionTool.hpp" 00038 #include "TopoDS_Shape.hxx" 00039 #include "TopoDS_Compound.hxx" 00040 #include "TopAbs_Orientation.hxx" 00041 #include "TopOpeBRep_Point2d.hxx" 00042 #include "TColgp_Array1OfPnt.hxx" 00043 #include "TColgp_HArray1OfPnt.hxx" 00044 #include "TColStd_HArray1OfBoolean.hxx" 00045 #include "TColgp_Array1OfVec.hxx" 00046 #include "TColStd_Array1OfReal.hxx" 00047 #include "TColStd_Array1OfInteger.hxx" 00048 #include "GC_MakeArcOfCircle.hxx" 00049 #include "GC_MakeCircle.hxx" 00050 #include "Geom_Circle.hxx" 00051 #include "Geom_SurfaceOfLinearExtrusion.hxx" 00052 #include "Geom_RectangularTrimmedSurface.hxx" 00053 #include "Geom_BSplineCurve.hxx" 00054 #include "Handle_Geom_RectangularTrimmedSurface.hxx" 00055 #include "GC_MakeArcOfHyperbola.hxx" 00056 #include "GC_MakeArcOfParabola.hxx" 00057 #include "GC_MakeArcOfEllipse.hxx" 00058 #include "GC_MakeSegment.hxx" 00059 #include "GC_MakeTrimmedCone.hxx" 00060 #include "GC_MakeTrimmedCylinder.hxx" 00061 #include "gce_MakeElips.hxx" 00062 #include "BRepFilletAPI_MakeFillet.hxx" 00063 #include "BRepFilletAPI_MakeChamfer.hxx" 00064 #include "BRepAdaptor_CompCurve.hxx" 00065 #include "GeomAPI_Interpolate.hxx" 00066 #include "BRepFilletAPI_MakeFillet2d.hxx" 00067 #include "ChFi2d_ConstructionError.hxx" 00068 #include "Geom_BezierCurve.hxx" 00069 #include "BndLib_AddSurface.hxx" 00070 #include "Handle_Geom_Plane.hxx" 00071 #include "Handle_Geom_OffsetCurve.hxx" 00072 #include "Geom_OffsetCurve.hxx" 00073 #include "BRepExtrema_DistShapeShape.hxx" 00074 #include "Extrema_ExtPC.hxx" 00075 #include "BRepPrimAPI_MakePrism.hxx" 00076 #include "BRepSweep_Revol.hxx" 00077 #include "BRepPrimAPI_MakeCone.hxx" 00078 #include "BRepOffsetAPI_ThruSections.hxx" 00079 #include "BRepLib_FuseEdges.hxx" 00080 #include "BRepOffsetAPI_MakePipe.hxx" 00081 #include "BRepPrimAPI_MakeTorus.hxx" 00082 #include "BRepPrimAPI_MakeCylinder.hxx" 00083 #include "BRepBuilderAPI_Transform.hxx" 00084 #include "BRepAdaptor_Curve.hxx" 00085 #include "GC_MakeEllipse.hxx" 00086 #include "BRepBuilderAPI_MakeEdge.hxx" 00087 #include "BRepAdaptor_Surface.hxx" 00088 #include "BRepBuilderAPI_MakeFace.hxx" 00089 #include "ShapeExtend_Status.hxx" 00090 #include "BRepOffsetAPI_MakeThickSolid.hxx" 00091 #include "BRepBuilderAPI_Sewing.hxx" 00092 #include "BRepBuilderAPI_Copy.hxx" 00093 #include "LocOpe_SplitShape.hxx" 00094 #include "BRep_Tool.hxx" 00095 #include "BRep_Builder.hxx" 00096 #include "GProp_GProps.hxx" 00097 #include "BRepGProp.hxx" 00098 #include "TopoDS.hxx" 00099 #include "ShapeFix.hxx" 00100 #include "TopologyBridge.hpp" 00101 #include "ProgressTool.hpp" 00102 #include "BRepAlgoAPI_Fuse.hxx" 00103 #include "BRepAlgoAPI_Cut.hxx" 00104 #include "BRepAlgoAPI_Section.hxx" 00105 #include "BRepAlgoAPI_Common.hxx" 00106 #include "BRepPrimAPI_MakeSphere.hxx" 00107 #include "BRepPrimAPI_MakeBox.hxx" 00108 #include "BRepPrimAPI_MakeWedge.hxx" 00109 #include "BRepTools_WireExplorer.hxx" 00110 #include "Handle_Geom_TrimmedCurve.hxx" 00111 #include "Handle_ShapeBuild_ReShape.hxx" 00112 #include "ShapeBuild_ReShape.hxx" 00113 #include "Handle_Geom_RectangularTrimmedSurface.hxx" 00114 #include "BndLib_Add3dCurve.hxx" 00115 #include "TopOpeBRep_EdgesIntersector.hxx" 00116 #include "TopExp_Explorer.hxx" 00117 #include "TopExp.hxx" 00118 #ifndef OCC_VERSION_MINOR 00119 #include "Standard_Version.hxx" 00120 #endif 00121 00122 #include "OCCDrawTool.hpp" 00123 #include "OCCModifyEngine.hpp" 00124 #include "OCCQueryEngine.hpp" 00125 #include "CubitMessage.hpp" 00126 #include "CubitDefines.h" 00127 #include "TopTools_DataMapOfShapeInteger.hxx" 00128 #include "BRepFeat_SplitShape.hxx" 00129 #include "TopOpeBRep_ShapeIntersector.hxx" 00130 #include "TopTools_ListIteratorOfListOfShape.hxx" 00131 #include "CubitUtil.hpp" 00132 #include "GeometryQueryTool.hpp" 00133 #include "GeometryModifyTool.hpp" 00134 #include "OCCCoEdge.hpp" 00135 #include "OCCLoop.hpp" 00136 #include "OCCSurface.hpp" 00137 #include "OCCShell.hpp" 00138 #include "OCCLump.hpp" 00139 #include "OCCBody.hpp" 00140 #include "OCCCurve.hpp" 00141 #include "OCCPoint.hpp" 00142 #include "OCCAttribSet.hpp" 00143 #include "CubitFileIOWrapper.hpp" 00144 #include "Body.hpp" 00145 #include "GfxDebug.hpp" 00146 #include "RefFace.hpp" 00147 #include "CpuTimer.hpp" 00148 #include "AppUtil.hpp" 00149 #include "SphereEvaluator.hpp" 00150 #include "CylinderEvaluator.hpp" 00151 #include "GfxPreview.hpp" 00152 #include <vector> 00153 #include "CGMEngineDynamicLoader.hpp" 00154 00155 CGM_ENGINE_EXPORT_CREATE_GME(OpenCascade) 00156 { 00157 return OCCModifyEngine::instance(); 00158 } 00159 00160 OCCModifyEngine* OCCModifyEngine::instance_ = 0; 00161 typedef std::map<OCCSurface*, std::pair<CubitVector, int> >::value_type valType; 00162 typedef std::map<OCCCurve*, std::pair<CubitVector, int> >::value_type valType2; 00163 #define DEBUG 00164 double TOL = 0.0; 00165 //=============================================================================== 00166 // Function : OCCModifyEngine 00167 // Member Type: PUBLIC 00168 // Description: constructor 00169 // Author : John Fowler 00170 // Date : 10/02 00171 //=============================================================================== 00172 OCCModifyEngine::OCCModifyEngine() 00173 { 00174 // assert( !instance_ ); 00175 00176 // add this modify engine to geometrymodifytool 00177 GeometryModifyTool::instance()->add_gme(this); 00178 TOL = OCCQueryEngine::instance()->get_sme_resabs_tolerance(); 00179 } 00180 00181 00182 //=============================================================================== 00183 // Function : ~OCCModifyEngine 00184 // Member Type: PUBLIC 00185 // Description: destructor 00186 // Author : John Fowler 00187 // Date : 10/02 00188 //=============================================================================== 00189 OCCModifyEngine::~OCCModifyEngine() 00190 { 00191 instance_ = 0; 00192 } 00193 00194 //=============================================================================== 00195 // Function : make_Point 00196 // Member Type: PUBLIC 00197 // Description: make a geometric entity point 00198 // Author : Jane Hu 00199 // Date : 10/07 00200 //=============================================================================== 00201 TBPoint* OCCModifyEngine::make_Point( CubitVector const& point) const 00202 { 00203 gp_Pnt pt = gp_Pnt( point.x(), point.y(), point.z()); 00204 TopoDS_Vertex theVertex = BRepBuilderAPI_MakeVertex(pt); 00205 00206 // Create a new Point object 00207 return OCCQueryEngine::instance()->populate_topology_bridge( theVertex, true ); 00208 } 00209 00210 //=============================================================================== 00211 // Function : make_Curve 00212 // This function creates a curve given an existing curve, copy. 00213 // Member Type: PUBLIC 00214 // Description: make a curve 00215 // Author : Jane Hu 00216 // Date : 01/08 00217 //=============================================================================== 00218 Curve* OCCModifyEngine::make_Curve(Curve * curve_ptr, std::map<TopologyBridge*, TopologyBridge*> * /*old_tb_to_new_tb*/) const 00219 { 00220 OCCCurve* occ_curve = CAST_TO(curve_ptr, OCCCurve); 00221 if (!occ_curve) 00222 { 00223 PRINT_ERROR("Cannot create an OCC curve from the given curve.\n" 00224 "Possible incompatible geometry engines.\n"); 00225 return (Curve *)NULL; 00226 } 00227 00228 TopoDS_Edge *theEdge = occ_curve->get_TopoDS_Edge(); 00229 00230 BRepBuilderAPI_Copy api_copy(*theEdge); 00231 00232 TopoDS_Shape newShape = api_copy.ModifiedShape(*theEdge); 00233 00234 TopoDS_Edge newEdge = TopoDS::Edge(newShape); 00235 00236 OCCQueryEngine::instance()->copy_attributes(*theEdge, newEdge); 00237 00238 return OCCQueryEngine::instance()->populate_topology_bridge(newEdge, true); 00239 } 00240 00241 //=============================================================================== 00242 // Function : make_Curve 00243 // Member Type: PUBLIC 00244 // Description: make a curve by projecting a straight line defined by 00245 // point1_ptr, and point2_ptr onto face_ptr, third_point 00246 // is used for curves that could be periodic to dertermine 00247 // the correct direction. 00248 // Author : Jane Hu 00249 // Date : 01/08 00250 //=============================================================================== 00251 Curve* OCCModifyEngine::make_Curve( TBPoint const* point1_ptr, 00252 TBPoint const* point2_ptr, 00253 Surface* face_ptr, 00254 const CubitVector * third_point) const 00255 { 00256 assert (point1_ptr != NULL && point2_ptr != NULL); 00257 GeometryType type = STRAIGHT_CURVE_TYPE; 00258 CubitBoolean closed = CUBIT_FALSE; 00259 DLIList<CubitVector*> mid_points; 00260 Curve* curve = NULL; 00261 if (point1_ptr != point2_ptr) 00262 curve = make_Curve(type, point1_ptr, point2_ptr, mid_points); 00263 else //could be a closed shape 00264 { 00265 if(third_point != NULL && face_ptr != NULL) 00266 { 00267 closed = CUBIT_TRUE; 00268 TBPoint * Pnt = make_Point(*third_point); 00269 curve = make_Curve(type, point1_ptr, Pnt, mid_points); 00270 } 00271 else 00272 { 00273 PRINT_ERROR("Cannot create an OCC curve from the given duplicated points.\n"); 00274 return (Curve *)NULL; 00275 } 00276 } 00277 00278 Curve* new_curve = NULL; 00279 if(face_ptr == NULL) 00280 return curve; 00281 00282 DLIList<TBPoint*> points; 00283 00284 new_curve = 00285 CAST_TO(curve, OCCCurve)-> 00286 project_curve(face_ptr, points, closed, third_point); 00287 OCCQueryEngine::instance()->delete_solid_model_entities( curve ); 00288 return new_curve; 00289 } 00290 00291 //=============================================================================== 00292 // Function : make_Curve 00293 // Member Type: PUBLIC 00294 // Description: make a spline curve by using the points and tangents. 00295 // size of point list and tangents must be the same. 00296 // values in the tangent list may be null. 00297 // Author : Jane Hu 00298 // Date : 01/11 00299 //=============================================================================== 00300 Curve* OCCModifyEngine::make_Curve( DLIList<CubitVector*>& point_list, 00301 DLIList<CubitVector*>& point_tangents) const 00302 { 00303 if (point_list.size() != point_tangents.size()) 00304 { 00305 PRINT_ERROR(" point list and tangent list must have same size\n"); 00306 return (Curve *)NULL; 00307 } 00308 00309 if(point_list.size() < 2) 00310 { 00311 PRINT_ERROR(" Can't create a curve with less than 2 points\n"); 00312 return (Curve *)NULL; 00313 } 00314 00315 int size = point_list.size(); 00316 Handle(TColgp_HArray1OfPnt) points = new TColgp_HArray1OfPnt(1, size); 00317 TColgp_Array1OfVec tangents(1, size); 00318 Handle(TColStd_HArray1OfBoolean) tangentFlags = 00319 new TColStd_HArray1OfBoolean(1,size); 00320 gp_Pnt pt, pt1; 00321 CubitVector *pt_vec, *tangent_vec; 00322 gp_Vec tangent; 00323 for (int i = 1 ; i <= size; i++) 00324 { 00325 pt_vec = point_list.get_and_step(); 00326 pt.SetCoord(pt_vec->x(), pt_vec->y(), pt_vec->z()); 00327 if(i == 1) 00328 pt1 = pt; 00329 points->SetValue(i, pt); 00330 00331 tangent_vec = point_tangents.get_and_step(); 00332 if (!tangent_vec) 00333 { 00334 tangents.SetValue(i,tangent); 00335 tangentFlags->SetValue(i, CUBIT_FALSE); 00336 } 00337 else 00338 { 00339 tangent.SetCoord(tangent_vec->x(), tangent_vec->y(), 00340 tangent_vec->z()); 00341 tangents.SetValue(i,tangent); 00342 tangentFlags->SetValue(i, CUBIT_TRUE); 00343 } 00344 } 00345 GeomAPI_Interpolate interpolater(points, CUBIT_FALSE, TOL); 00346 interpolater.Load(tangents, tangentFlags); 00347 interpolater.Perform() ; 00348 Handle(Geom_BSplineCurve) pcurve; 00349 if(interpolater.IsDone()) 00350 pcurve = interpolater.Curve(); 00351 00352 else 00353 { 00354 PRINT_ERROR("Can't create a curve using provided points and tangents.\n"); 00355 return (Curve *)NULL; 00356 } 00357 00358 TopoDS_Edge topo_edge = BRepBuilderAPI_MakeEdge(pcurve, pt1, pt); 00359 return OCCQueryEngine::instance()->populate_topology_bridge(topo_edge, true); 00360 } 00361 00362 //=============================================================================== 00363 // Function : make_Curve 00364 // Member Type: PUBLIC 00365 // Description: make a spline curve by using the points on surface. 00366 // Author : Jane Hu 00367 // Date : 01/08 00368 //=============================================================================== 00369 Curve* OCCModifyEngine::make_Curve( GeometryType curve_type, 00370 TBPoint const* point1_ptr, 00371 TBPoint const* point2_ptr, 00372 DLIList<CubitVector*>& vector_list, 00373 Surface* face_ptr) const 00374 { 00375 assert(point1_ptr != NULL && point2_ptr != NULL); 00376 00377 if (curve_type != SPLINE_CURVE_TYPE 00378 && curve_type != STRAIGHT_CURVE_TYPE) 00379 { 00380 PRINT_ERROR("Cannot create an OCC curve from the given curve_type.\n" 00381 "Candidates are SPLINE_CURVE_TYPE and STRAIGHT_CURVE_TYPE.\n"); 00382 return (Curve *)NULL; 00383 } 00384 00385 if (curve_type == STRAIGHT_CURVE_TYPE) 00386 return make_Curve(curve_type, point1_ptr, point2_ptr, NULL); 00387 00388 OCCPoint* occ_point1 = CAST_TO(const_cast<TBPoint*>(point1_ptr), OCCPoint); 00389 OCCPoint* occ_point2 = CAST_TO(const_cast<TBPoint*>(point2_ptr), OCCPoint); 00390 00391 if (occ_point1 == NULL || occ_point2 == NULL) 00392 { 00393 PRINT_ERROR("Cannot create an OCC curve from the given points.\n" 00394 "Possible incompatible geometry engines.\n"); 00395 return (Curve *)NULL; 00396 } 00397 00398 //project all points on the surface if possible 00399 OCCSurface* occ_face = NULL; 00400 if (face_ptr != NULL) 00401 occ_face = CAST_TO(face_ptr, OCCSurface); 00402 00403 gp_Pnt pt; 00404 int size = vector_list.size(); 00405 Handle(TColgp_HArray1OfPnt) points = new TColgp_HArray1OfPnt(1, size); 00406 CubitVector vector; 00407 CubitVector closest_location; 00408 for(int i = 1; i <= size; i++) 00409 { 00410 vector = *vector_list.get_and_step(); 00411 pt.SetCoord(vector.x(), vector.y(), vector.z()); 00412 00413 if (occ_face != NULL) 00414 { 00415 occ_face->closest_point(vector, &closest_location); 00416 pt.SetCoord(closest_location.x(), closest_location.y(), closest_location.z()) ; 00417 } 00418 00419 points->SetValue(i, pt); 00420 } 00421 00422 //make curve according to the curve type. 00423 if(curve_type == SPLINE_CURVE_TYPE) 00424 { 00425 if (size < 3) 00426 { 00427 PRINT_ERROR(" Must have at least 3 points to make a spline. \n"); 00428 return (Curve*) NULL; 00429 } 00430 00431 GeomAPI_Interpolate spline(points, CUBIT_FALSE, TOL); 00432 spline.Perform(); 00433 if(spline.IsDone()) 00434 { 00435 Handle_Geom_BSplineCurve curve = spline.Curve(); 00436 TopoDS_Vertex * vt1 = occ_point1->get_TopoDS_Vertex(); 00437 TopoDS_Vertex * vt2 = occ_point2->get_TopoDS_Vertex(); 00438 TopoDS_Edge new_edge = BRepBuilderAPI_MakeEdge(curve, *vt1, *vt2); 00439 return OCCQueryEngine::instance()->populate_topology_bridge(new_edge, true); 00440 } 00441 } 00442 00443 return (Curve*) NULL; 00444 } 00445 00446 //=============================================================================== 00447 // Function : make_Curve 00448 // Member Type: PUBLIC 00449 // Description: make a curve 00450 // For STRAIGHT_CURVE_TYPE: 00451 // intermediate_point_ptr is not used 00452 // 00453 // For PARABOLA_CURVE_TYPE 00454 // intermediate_point_ptr is the tip of the parabola 00455 // 00456 // For HYPERBOLA_CURVE_TYPE 00457 // intermediate_point_ptr is the center of its two foci 00458 // 00459 // For ELLIPSE_CURVE_TYPE 00460 // intermediate_point_ptr is the center of the ellipse 00461 // the two points are vertices, one gives the major radius, 00462 // the other point gives the minor radius. 00463 // 00464 // For ARC_CURVE_TYPE 00465 // arc passes three points 00466 // 00467 // Author : Jane Hu 00468 // Date : 01/08 00469 //=============================================================================== 00470 Curve* OCCModifyEngine::make_Curve( GeometryType curve_type, 00471 TBPoint const* point1_ptr, 00472 TBPoint const* point2_ptr, 00473 CubitVector const* intermediate_point_ptr) const 00474 { 00475 assert (point1_ptr != NULL && point2_ptr != NULL); 00476 DLIList<CubitVector*> mid_points; 00477 if (intermediate_point_ptr) 00478 { 00479 CubitVector mid_point = *intermediate_point_ptr; 00480 mid_points.append(&mid_point); 00481 } 00482 00483 CubitVector v1(point1_ptr->coordinates()); 00484 CubitVector v2(point2_ptr->coordinates()); 00485 00486 gp_Pnt pt1(v1.x(),v1.y(), v1.z()); 00487 gp_Pnt pt2(v2.x(),v2.y(), v2.z()); 00488 00489 CubitVector v3; 00490 gp_Pnt pt3; 00491 00492 Handle(Geom_TrimmedCurve) curve_ptr; 00493 if(intermediate_point_ptr != NULL) 00494 { 00495 v3 = *intermediate_point_ptr; 00496 pt3.SetCoord(v3.x(),v3.y(), v3.z()); 00497 } 00498 00499 if (curve_type == STRAIGHT_CURVE_TYPE) 00500 { 00501 //make sure the two points are not coincident 00502 if(v1.about_equal(v2)) 00503 { 00504 PRINT_ERROR("Can't create a line from two identical points.\n"); 00505 return (Curve *)NULL; 00506 } 00507 curve_ptr = GC_MakeSegment(pt1,pt2); 00508 } 00509 00510 else if (curve_type == ARC_CURVE_TYPE) 00511 { 00512 assert(intermediate_point_ptr != NULL); 00513 curve_ptr = GC_MakeArcOfCircle(pt1, pt3, pt2); 00514 } 00515 00516 else if (curve_type == ELLIPSE_CURVE_TYPE) 00517 { 00518 assert(intermediate_point_ptr != NULL); 00519 00520 gp_Pnt center(v3.x(), v3.y(), v3.z()); 00521 00522 gp_Elips ellipse; 00523 gce_MakeElips ellipse1(pt1 , pt2 , center); 00524 if(ellipse1.IsDone()) 00525 ellipse = ellipse1.Value(); 00526 else if(!ellipse1.IsDone() && ellipse1.Status() == gce_InvertAxis) 00527 { 00528 gce_MakeElips ellipse2(pt2, pt1, center); 00529 if(ellipse2.IsDone()) 00530 ellipse = ellipse2.Value(); 00531 else 00532 { 00533 PRINT_ERROR("Can't create an ellipse from give 3 points.\n"); 00534 return (Curve *)NULL; 00535 } 00536 } 00537 else 00538 { 00539 PRINT_ERROR("Can't create an ellipse from give 3 points.\n"); 00540 return (Curve *)NULL; 00541 } 00542 curve_ptr = GC_MakeArcOfEllipse(ellipse, pt1, pt2, CUBIT_TRUE); 00543 } 00544 00545 else if(curve_type == PARABOLA_CURVE_TYPE || 00546 curve_type == HYPERBOLA_CURVE_TYPE) 00547 { 00548 assert(intermediate_point_ptr != NULL); 00549 00550 //find the directrix and focus of the parabola 00551 //or the axis, major radius and minor radius of the hyperbola 00552 CubitVector width_vec = v2 - v1; 00553 if(width_vec.length_squared() < TOL * TOL) 00554 { 00555 PRINT_ERROR("Cannot create a parabola or hyperbola curve from the given points.\n" 00556 "2 end points are the same.\n"); 00557 return (Curve *)NULL; 00558 } 00559 00560 CubitVector midpoint_vec = (v1 + v2)/2.0; 00561 CubitVector height_vec = midpoint_vec - v3; 00562 gp_Pnt center(v3.x(), v3.y(), v3.z()); 00563 00564 if (height_vec.length_squared() < TOL * TOL) 00565 { 00566 PRINT_ERROR("Cannot create a parabola or hyperbola curve from the given points.\n" 00567 "3 points are in the same line.\n"); 00568 return (Curve *)NULL; 00569 } 00570 CubitVector x = height_vec; 00571 x.normalize(); 00572 gp_Dir x_dir(x.x(), x.y(), x.z()); 00573 00574 CubitVector N = x * (v2 - v1); 00575 if (N.length_squared() < TOL * TOL) 00576 { 00577 PRINT_ERROR("Cannot create a parabola or hyperbola curve from the given points.\n" 00578 "3 points are in the same line.\n"); 00579 return (Curve *)NULL; 00580 } 00581 N.normalize(); 00582 gp_Dir N_dir(N.x(), N.y(), N.z()); 00583 00584 gp_Ax2 axis(center, N_dir, x_dir); 00585 00586 if(curve_type == HYPERBOLA_CURVE_TYPE) 00587 { 00588 // (focus2) (v3) . (v2) 00589 // . . . (midpoint = focus1) 00590 // . (v1) 00591 CubitVector focus2 = 2 * v3 - midpoint_vec; 00592 00593 //according to the definition of hyperbola, 00594 //2 * a = length(v2 - focus2)-length(v2 - focus1) 00595 00596 double major = (v2 - focus2).length()/2.0 - (v2 - midpoint_vec).length()/2.0; 00597 00598 // if a = 1/2 length major axis, b = 1/2 length minor axis and 00599 // c = distance center to focus, then a*a + b*b = c*c 00600 00601 double c_squared = (midpoint_vec - v3).length_squared(); 00602 double minor = sqrt(c_squared - major*major ); 00603 gp_Hypr hypt(axis, major, minor); 00604 curve_ptr = 00605 GC_MakeArcOfHyperbola(hypt, pt1, pt2, CUBIT_TRUE); 00606 } 00607 00608 else 00609 { 00610 // Find the focus of this parabola. 00611 // Since for a parabola with its peak at the origin, y = (1/(4*a))*x^2, 00612 // and since we have restricted this parabola to be symmetric (per the 00613 // FastQ method, see the FastQ file getwt.f), we can use the following 00614 // relationship to 00615 // determine "a", the distance the focus lies from the peak on the line 00616 // formed by the peak and the midpoint of the start and end points` 00617 double a = width_vec.length_squared()/(16. * height_vec.length()); 00618 gp_Parab parab(axis, a); 00619 curve_ptr = 00620 GC_MakeArcOfParabola(parab, pt1, pt2, CUBIT_TRUE); 00621 } 00622 } 00623 00624 else 00625 { 00626 PRINT_ERROR("In OCCModifyEngine::make_Curve\n" 00627 " Invalid curve type.\n"); 00628 return (Curve *)NULL; 00629 } 00630 00631 OCCPoint* occ_pt1 = CAST_TO(const_cast<TBPoint*>(point1_ptr),OCCPoint); 00632 OCCPoint* occ_pt2 = CAST_TO(const_cast<TBPoint*>(point2_ptr),OCCPoint); 00633 TopoDS_Vertex * vt1 = occ_pt1->get_TopoDS_Vertex(); 00634 TopoDS_Vertex * vt2 = occ_pt2->get_TopoDS_Vertex(); 00635 TopoDS_Edge new_edge = BRepBuilderAPI_MakeEdge(curve_ptr, *vt1, *vt2); 00636 return OCCQueryEngine::instance()->populate_topology_bridge(new_edge, true); 00637 } 00638 00639 Surface* OCCModifyEngine::make_Surface( Surface *surface_ptr, 00640 std::map< TopologyBridge*, TopologyBridge* > * /*old_tb_to_new_tb*/) const 00641 { 00642 // Set extended_from argument to CUBIT_FALSE by default 00643 return make_Surface(surface_ptr, CUBIT_FALSE); 00644 } 00645 00646 //=============================================================================== 00647 // Function : make_Surface 00648 // This function creates a surface given an existing surface, copy. 00649 // Member Type: PRIVATE 00650 // Description: make a surface, OCC allows to create a stand along surface, 00651 // however the CGM has a design of making all surfaces in a (sheet) 00652 // body. This will add complexity on all free surface related 00653 // calculation and modification, and adding potential bugs too. 00654 // Author : Jane Hu 00655 // Date : 02/08 00656 //=============================================================================== 00657 Surface* OCCModifyEngine::make_Surface( Surface * surface_ptr, 00658 CubitBoolean extended_from) const 00659 { 00660 OCCSurface* occ_surface = CAST_TO(surface_ptr, OCCSurface); 00661 if (!occ_surface) 00662 { 00663 PRINT_ERROR("Cannot create an OCC surface from the given surface.\n" 00664 "Possible incompatible geometry engines.\n"); 00665 return (Surface *)NULL; 00666 } 00667 00668 //Start of the codes 00669 double UMax, VMax, UMin, VMin; 00670 occ_surface->get_param_range_U(UMin, UMax); 00671 occ_surface->get_param_range_V(VMin, VMax); 00672 00673 TopoDS_Face *theFace = occ_surface->get_TopoDS_Face(); 00674 00675 if( !theFace) 00676 { 00677 PRINT_ERROR("Cannot create an OCC surface from the given surface.\n" 00678 "Possible incompatible geometry engines.\n"); 00679 return (Surface *)NULL; 00680 } 00681 00682 TopoDS_Face newFace; 00683 BRepAdaptor_Surface asurface(*theFace); 00684 00685 CubitBox bounding_box = GeometryQueryTool::instance()->model_bounding_box(); 00686 double const height = 2*(bounding_box.diagonal()).length(); 00687 CubitBox box = occ_surface->bounding_box(); 00688 double ratio = height/(box.diagonal().length()); 00689 00690 double middleU = (UMin + UMax)/2.0; 00691 double middleV = (VMin + VMax)/2.0; 00692 double U1 = middleU - (UMax-UMin)/2.0 * ratio; 00693 double U2 = middleU + (UMax-UMin)/2.0 * ratio; 00694 double V1 = middleV - (VMax - VMin)/2.0 * ratio; 00695 double V2 = middleV + (VMax - VMin)/2.0 * ratio; 00696 00697 if (extended_from == CUBIT_TRUE) 00698 { 00699 // We need to get the type of surface. 00700 GeometryType type = occ_surface->geometry_type(); 00701 if (type == PLANE_SURFACE_TYPE) 00702 { 00703 gp_Pln plane = asurface.Plane(); 00704 newFace = BRepBuilderAPI_MakeFace(plane, U1, U2, V1, V2); 00705 } 00706 else if(type == CONE_SURFACE_TYPE) 00707 { 00708 //make an infinite cone. 00709 //Given this lets create another face that is extended from it. 00710 if(asurface.GetType() == GeomAbs_Cone) 00711 { 00712 gp_Cone cone = asurface.Cone(); 00713 #if OCC_VERSION_MINOR > 5 00714 newFace = BRepBuilderAPI_MakeFace(cone, U1, U2, V1, V2); 00715 #else 00716 gp_Pnt Apex = cone.Apex(); 00717 double semi_angle = cone.SemiAngle(); 00718 gp_Pnt p2; 00719 double radius2; 00720 gp_XYZ xyz; 00721 if (semi_angle > 0) 00722 xyz = Apex.XYZ() + cone.Position().Direction().XYZ()*height; 00723 else 00724 xyz = Apex.XYZ() - cone.Position().Direction().XYZ()*height; 00725 00726 p2.SetXYZ(xyz); 00727 radius2 = height * tan(fabs(semi_angle)); 00728 Handle(Geom_RectangularTrimmedSurface) trimmed_cone; 00729 trimmed_cone = GC_MakeTrimmedCone(Apex, p2, 0, radius2); 00730 #if OCC_VERSION_MAINTENANCE < 2 00731 newFace = BRepBuilderAPI_MakeFace(trimmed_cone); 00732 #else 00733 newFace = BRepBuilderAPI_MakeFace(trimmed_cone, TOL); 00734 #endif 00735 #endif 00736 } 00737 else 00738 { 00739 gp_Cylinder cylinder = asurface.Cylinder(); 00740 #if OCC_VERSION_MINOR > 5 00741 newFace = BRepBuilderAPI_MakeFace(cylinder, U1, U2, V1, V2); 00742 #else 00743 double radius = cylinder.Radius(); 00744 gp_Ax1 axis = cylinder.Axis(); 00745 Handle(Geom_RectangularTrimmedSurface) trimmed_cyl; 00746 trimmed_cyl = GC_MakeTrimmedCylinder(axis, radius, height); 00747 #if OCC_VERSION_MAINTENANCE < 2 00748 newFace = BRepBuilderAPI_MakeFace(trimmed_cyl); 00749 #else 00750 newFace = BRepBuilderAPI_MakeFace(trimmed_cyl, TOL); 00751 #endif 00752 #endif 00753 } 00754 } 00755 else if(type == SPHERE_SURFACE_TYPE) 00756 { 00757 //make a whole sphere. 00758 gp_Sphere sphere = asurface.Sphere(); 00759 newFace = BRepBuilderAPI_MakeFace(sphere); 00760 } 00761 else if(type == TORUS_SURFACE_TYPE) 00762 { 00763 //make a whole torus 00764 gp_Torus torus = asurface.Torus(); 00765 newFace = BRepBuilderAPI_MakeFace(torus); 00766 } 00767 else if(type == SPLINE_SURFACE_TYPE ) 00768 { 00769 //extend the surfaces using the equation if possible. 00770 Handle(Geom_BezierSurface) bezier = asurface.Bezier(); 00771 Handle(Geom_Surface) p_surf = bezier; 00772 #if OCC_VERSION_MINOR > 5 00773 newFace = BRepBuilderAPI_MakeFace(p_surf, U1, U2, V1, V2, TOL); 00774 #else 00775 #if OCC_VERSION_MAINTENANCE < 2 00776 newFace = BRepBuilderAPI_MakeFace(p_surf, U1, U2, V1, V2); 00777 #else 00778 newFace = BRepBuilderAPI_MakeFace(p_surf, U1, U2, V1, V2, TOL); 00779 #endif 00780 #endif 00781 } 00782 } 00783 00784 else 00785 { 00786 BRepBuilderAPI_Copy api_copy(*theFace); 00787 TopoDS_Shape newShape = api_copy.ModifiedShape(*theFace); 00788 newFace = TopoDS::Face(newShape); 00789 } 00790 00791 Surface *surface = OCCQueryEngine::instance()->populate_topology_bridge( 00792 newFace, CUBIT_TRUE); 00793 00794 return surface; 00795 } 00796 00797 //=============================================================================== 00798 // Function : make_Surface 00799 // Member Type: PUBLIC 00800 // Description: make a surface of type surface_type, given the list of curves. 00801 // check edges option is done in GeometryModifyTool level, so 00802 // disregard this option. 00803 // Author : Jane Hu 00804 // Date : 02/08 00805 //=============================================================================== 00806 Surface* OCCModifyEngine::make_Surface( GeometryType surface_type, 00807 DLIList<Curve*>& curve_list, 00808 Surface * old_surface_ptr, 00809 bool check_edges) const 00810 { 00811 //Create TopoDS_Edge list to make a surface. 00812 DLIList<DLIList<TopoDS_Edge*>*> topo_edges_loops; 00813 curve_list.reset() ; 00814 00815 //check no intersections of the TopoDS_Edge's. 00816 //need to check that no intersection in the middle of the curves, not at 00817 //vertices or out of boundary. 00818 00819 int count = 0; //intersection point should be the same as curve_list size. 00820 for ( int i = 0 ; i < curve_list.size()-1 ; i++ ) 00821 { 00822 for(int j = i+1; j < curve_list.size(); j ++) 00823 { 00824 DLIList<CubitVector> intscts; 00825 CubitBoolean bounded = CUBIT_TRUE;//dummy arg. 00826 CubitBoolean closest = CUBIT_TRUE;//dummy arg. 00827 CubitStatus yes_int = 00828 OCCQueryEngine::instance()->get_intersections(curve_list[i], 00829 curve_list[j], intscts, bounded, closest); 00830 if(yes_int) 00831 { 00832 //check intscts point should be vertex or outside boundary. 00833 if (intscts.size() > 2 ) 00834 { 00835 PRINT_ERROR("In OCCModifyEngine::make_Surface\n" 00836 " Cannot make Surface with intersecting curves.\n"); 00837 return (Surface *)NULL; 00838 } 00839 else 00840 { 00841 for(int k = 0; k < intscts.size(); k++) 00842 { 00843 CubitVector &v = intscts.get_and_step(); 00844 CubitPointContainment is_on = CAST_TO(curve_list[i],OCCCurve)-> 00845 point_containment(v); 00846 if (is_on == CUBIT_PNT_BOUNDARY) 00847 { 00848 is_on = CAST_TO(curve_list[j],OCCCurve)-> 00849 point_containment(v); 00850 if (is_on == CUBIT_PNT_BOUNDARY) 00851 count++; 00852 } 00853 else if(is_on == CUBIT_PNT_INSIDE) 00854 { 00855 PRINT_ERROR("In OCCModifyEngine::make_Surface\n" 00856 " Cannot make Surface with intersecting curves.\n"); 00857 return (Surface *)NULL; 00858 } 00859 } 00860 } 00861 } 00862 } 00863 } 00864 00865 if (count > curve_list.size()) 00866 { 00867 PRINT_ERROR("In OCCModifyEngine::make_Surface\n" 00868 " Cannot make Surface with intersecting curves.\n"); 00869 return (Surface *)NULL; 00870 } 00871 00872 CubitStatus stat = sort_curves(curve_list, topo_edges_loops); 00873 if( stat == CUBIT_FAILURE ) //case of one disconnected curve , open wires 00874 { 00875 //loft curves. 00876 BRepOffsetAPI_ThruSections loft(CUBIT_FALSE); 00877 CubitStatus stat = do_loft(loft, topo_edges_loops); 00878 for (int i = 0; i < topo_edges_loops.size(); i++) 00879 { 00880 DLIList<TopoDS_Edge*>* topo_edges = topo_edges_loops.get_and_step(); 00881 for(int j = 0; j < topo_edges->size(); j++) 00882 topo_edges->pop(); 00883 delete topo_edges; 00884 topo_edges = NULL; 00885 } 00886 if(!stat) 00887 return (Surface*) NULL; 00888 00889 TopoDS_Shape shape = loft.Shape(); 00890 TopoDS_Shell shell = TopoDS::Shell(shape); 00891 TopExp_Explorer Ex; 00892 int num_surfaces = 0; 00893 TopoDS_Face topo_face ; 00894 for (Ex.Init(shell, TopAbs_FACE); Ex.More(); Ex.Next()) 00895 { 00896 topo_face = TopoDS::Face(Ex.Current()); 00897 num_surfaces ++; 00898 } 00899 00900 if(num_surfaces != 1) 00901 { 00902 PRINT_ERROR("In OCCModifyEngine::skin_surface\n" 00903 " Cannot create a skin surface for given curves.\n"); 00904 return (Surface*) NULL; 00905 } 00906 00907 Surface* surf = OCCQueryEngine::instance()->populate_topology_bridge(topo_face, CUBIT_TRUE); 00908 if (surf == NULL) 00909 { 00910 PRINT_ERROR("In OCCModifyEngine::skin_surfaces\n" 00911 " Cannot create a skin surface for given curves.\n"); 00912 return (Surface*) NULL; 00913 } 00914 00915 return surf; 00916 } 00917 00918 // Use the topo_edges to make a topo_face 00919 TopoDS_Face* topo_face; 00920 topo_face = make_TopoDS_Face(surface_type,topo_edges_loops, old_surface_ptr); 00921 00922 for (int i = 0; i < topo_edges_loops.size(); i++) 00923 { 00924 DLIList<TopoDS_Edge*>* topo_edges = topo_edges_loops.get_and_step(); 00925 for(int j = 0; j < topo_edges->size(); j++) 00926 topo_edges->pop(); 00927 delete topo_edges; 00928 topo_edges = NULL; 00929 } 00930 00931 if(!topo_face) 00932 { 00933 PRINT_ERROR("In OCCModifyEngine::make_Surface\n" 00934 " Cannot make Surface object.\n"); 00935 return (Surface *)NULL; 00936 } 00937 00938 // make the topology bridges for the face 00939 Surface *surface = OCCQueryEngine::instance()->populate_topology_bridge( 00940 *topo_face, CUBIT_TRUE); 00941 topo_face->Nullify(); 00942 delete topo_face; 00943 topo_face = NULL; 00944 00945 //Created new surface uses existing OCCPoints on the curves, but created 00946 //new curves, so remove the curves from the curvelist on those points. 00947 if(surface) 00948 { 00949 for(int i = 0; i < curve_list.size(); i++) 00950 { 00951 OCCCurve* test_c = CAST_TO(curve_list.get_and_step(), OCCCurve); 00952 DLIList<OCCPoint*> points; 00953 CAST_TO(surface, OCCSurface)->get_points(points); 00954 for(int j = 0; j < points.size(); j ++) 00955 points.get_and_step()->remove_curve(test_c); 00956 } 00957 } 00958 return surface ; 00959 } 00960 00961 CubitStatus OCCModifyEngine::do_loft(BRepOffsetAPI_ThruSections& loft, 00962 DLIList<DLIList<TopoDS_Edge*>*> loops) const 00963 { 00964 TopoDS_Edge new_edge; 00965 for(int i = 0; i < loops.size(); i++) 00966 { 00967 BRepBuilderAPI_MakeWire aWire; 00968 DLIList<TopoDS_Edge*> edges = *(loops.get_and_step()); 00969 00970 for(int j = 0; j < edges.size(); j++) 00971 { 00972 TopoDS_Edge* topo_edge = edges.get_and_step(); 00973 00974 BRepBuilderAPI_Copy api_copy(*topo_edge); 00975 TopoDS_Shape newShape = api_copy.ModifiedShape(*topo_edge); 00976 new_edge = TopoDS::Edge(newShape); 00977 aWire.Add(new_edge); 00978 } 00979 loft.AddWire(aWire.Wire()); 00980 } 00981 loft.Build(); 00982 if(!loft.IsDone()) 00983 { 00984 PRINT_ERROR("Curves can't be loft into a surface.\n"); 00985 return CUBIT_FAILURE; 00986 } 00987 return CUBIT_SUCCESS; 00988 } 00989 00990 //=============================================================================== 00991 // Function : sort_curves 00992 // Member Type: PROTECTED 00993 // Description: sort the curves so they are in order and make closed loop 00994 // Author : Jane Hu 00995 // Date : 03/08 00996 //=============================================================================== 00997 CubitStatus OCCModifyEngine::sort_curves(DLIList<Curve*> curve_list, 00998 DLIList<DLIList<TopoDS_Edge*>*>& topo_edges_loops)const 00999 { 01000 topo_edges_loops.clean_out(); 01001 CubitStatus stat = CUBIT_SUCCESS; 01002 std::vector< DLIList<TopoDS_Edge*>* > topo_edges(curve_list.size()); 01003 int size_in = curve_list.size(); 01004 for(int i = 0; i < size_in; i++) 01005 topo_edges[i] = new DLIList<TopoDS_Edge*>; 01006 01007 curve_list.reset() ; 01008 Curve const* curve_ptr = NULL ; 01009 OCCCurve* occ_curve = NULL; 01010 TopoDS_Edge* topo_edge = NULL; 01011 01012 OCCPoint* start = NULL; 01013 OCCPoint* end = NULL; 01014 DLIList<OCCPoint*> point_list; 01015 CubitBoolean new_end = CUBIT_FALSE; 01016 int size = curve_list.size(); 01017 01018 int count = 0; 01019 for ( int i = 0 ; i < size ; i++ ) 01020 { 01021 if (i == 0) 01022 new_end = CUBIT_TRUE; 01023 for(int j = 0; j < curve_list.size(); j ++) 01024 { 01025 curve_ptr = curve_list.get() ; 01026 occ_curve = CAST_TO(const_cast<Curve*>(curve_ptr), OCCCurve); 01027 01028 if(occ_curve == NULL) 01029 { 01030 PRINT_ERROR("In OCCModifyEngine::sort_curves\n" 01031 " Got a NULL pointer to OCCCurve\n") ; 01032 return CUBIT_FAILURE; 01033 } 01034 01035 point_list.clean_out(); 01036 occ_curve->get_points(point_list); 01037 //assert(point_list.size()==2); 01038 01039 if (i == 0) 01040 { 01041 start = point_list.get(); 01042 end = point_list.pop(); 01043 break; 01044 } 01045 01046 if(end->is_equal(*(point_list.get()), TOL) || 01047 end->is_equal(*(point_list.step_and_get()),TOL)) 01048 { 01049 end = point_list.step_and_get(); 01050 new_end = CUBIT_TRUE; 01051 break; 01052 } 01053 01054 else if(start->is_equal(*(point_list.get()), TOL) || 01055 start->is_equal(*(point_list.step_and_get()),TOL)) 01056 { 01057 start = end; 01058 end = point_list.step_and_get(); 01059 new_end = CUBIT_TRUE; 01060 break; 01061 } 01062 curve_list.step(); 01063 } 01064 01065 if (new_end)//found next curve 01066 { 01067 topo_edge = occ_curve->get_TopoDS_Edge(); 01068 topo_edges[count]->append(topo_edge); 01069 curve_list.remove(); 01070 if(start->is_equal( *end, TOL)) //formed a closed loop 01071 { 01072 i = -1; 01073 size = curve_list.size() ; 01074 topo_edges_loops.append(topo_edges[count]); 01075 count++; 01076 } 01077 else 01078 new_end = CUBIT_FALSE; 01079 } 01080 else 01081 { 01082 stat = CUBIT_FAILURE; 01083 i = -1; 01084 size = curve_list.size(); 01085 topo_edges_loops.append(topo_edges[count]); 01086 count++; 01087 } 01088 } 01089 01090 if( new_end == CUBIT_FALSE ) //case of one disconnected curve 01091 { 01092 topo_edges_loops.append(topo_edges[count]); 01093 stat = CUBIT_FAILURE; 01094 } 01095 01096 for(int i = 0; i < size_in; i++) 01097 { 01098 if(topo_edges[i]->size() == 0) 01099 { 01100 delete topo_edges[i]; 01101 topo_edges[i] = NULL; 01102 } 01103 } 01104 return stat; 01105 } 01106 //=============================================================================== 01107 // Function : make_TopoDS_Face 01108 // Member Type: PROTECTED 01109 // Description: make a opoDS_Face of type surface_type, given the list of 01110 // TopoDS_Edge. the TopoDS_Edge's should be in order in loops. 01111 // check edges option is done in GeometryModifyTool level, so 01112 // disregard this option. 01113 // Author : Jane Hu 01114 // Date : 02/08 01115 //=============================================================================== 01116 TopoDS_Face* OCCModifyEngine::make_TopoDS_Face(GeometryType surface_type, 01117 DLIList<DLIList<TopoDS_Edge*>*> topo_edges_list, 01118 Surface * old_surface_ptr)const 01119 { 01120 TopoDS_Face* topo_face = NULL; 01121 // Make sure a supported type of surface is being requested. 01122 if ( surface_type != PLANE_SURFACE_TYPE && 01123 surface_type != BEST_FIT_SURFACE_TYPE) 01124 { 01125 PRINT_WARNING("In OCCGeometryEngine::make_TopoDS_Face\n" 01126 " At this time, cannot make a TopoDS_Face that isn't" 01127 " planar or best fit.\n"); 01128 return topo_face; 01129 } 01130 01131 // Set the TopoDS_Face pointer, if requested. 01132 TopoDS_Face *fit_Face = NULL; 01133 Handle_Geom_Surface S; 01134 if ( old_surface_ptr != NULL ) 01135 { 01136 OCCSurface *surf = CAST_TO(old_surface_ptr, OCCSurface ); 01137 fit_Face = surf->get_TopoDS_Face(); 01138 S = BRep_Tool::Surface(*fit_Face); 01139 } 01140 01141 // Make a wire from the topo_edges. 01142 // Coincident TopoDS_Vertex will be deleted by OCC. 01143 if(topo_edges_list.size() == 0) 01144 return topo_face; 01145 01146 DLIList<TopoDS_Wire*> wires; 01147 GProp_GProps myProps; 01148 double max_area = 0.0; 01149 TopoDS_Wire* out_Wire = NULL; 01150 TopoDS_Wire test_Wire; 01151 DLIList<TopoDS_Edge*>* topo_edges; 01152 //check and make sure the outer loop is in the first 01153 for(int i = 0; i < topo_edges_list.size() ; i++) 01154 { 01155 topo_edges = topo_edges_list.get_and_step(); 01156 BRepBuilderAPI_MakeWire aWire(*(topo_edges->get())); 01157 for(int j = 1; j < topo_edges->size(); j++) 01158 aWire.Add(*(topo_edges->step_and_get())); 01159 01160 test_Wire = aWire.Wire(); 01161 wires.append(&test_Wire); 01162 01163 if (topo_edges_list.size() == 1) 01164 break; 01165 01166 BRepBuilderAPI_MakeFace made_face(test_Wire); 01167 01168 if (!made_face.IsDone()) 01169 { 01170 PRINT_ERROR("In OCCModifyEngine::make_TopoDS_Face\n" 01171 " Cannot find the best fit surface for given curves.\n"); 01172 return topo_face; 01173 } 01174 TopoDS_Face test_face = made_face.Face(); 01175 BRepGProp::SurfaceProperties(test_face, myProps); 01176 double area = myProps.Mass(); 01177 out_Wire = max_area > area ? out_Wire : &test_Wire; 01178 max_area = max_area > area ? max_area : area; 01179 } 01180 01181 if (out_Wire) 01182 { 01183 wires.remove(out_Wire); 01184 wires.insert_first(out_Wire); 01185 } 01186 01187 //create the TopoDS_Face 01188 CubitBoolean error = CUBIT_FALSE; 01189 01190 for(int i = 0; i < topo_edges_list.size() ; i++) 01191 { 01192 TopoDS_Wire *the_wire = wires.get_and_step(); 01193 if (i == 0) 01194 { 01195 if( old_surface_ptr != NULL ) 01196 { 01197 BRepBuilderAPI_MakeFace made_face(S, *the_wire); 01198 if (!made_face.IsDone()) 01199 { 01200 error = CUBIT_TRUE; 01201 break; 01202 } 01203 topo_face = new TopoDS_Face(made_face.Face()); 01204 } 01205 else 01206 { 01207 CubitBoolean is_planar = (surface_type == PLANE_SURFACE_TYPE ? 01208 CUBIT_TRUE : CUBIT_FALSE); 01209 BRepBuilderAPI_MakeFace made_face(*the_wire, is_planar); 01210 if (!made_face.IsDone()) 01211 { 01212 error = CUBIT_TRUE; 01213 break; 01214 } 01215 01216 topo_face = new TopoDS_Face(made_face.Face()); 01217 } 01218 } 01219 else 01220 { 01221 BRepBuilderAPI_MakeFace made_face(*topo_face, *the_wire); 01222 if (!made_face.IsDone()) 01223 { 01224 error = CUBIT_TRUE; 01225 break; 01226 } 01227 delete topo_face; 01228 topo_face = new TopoDS_Face(made_face.Face()); 01229 } 01230 } 01231 01232 if(error) 01233 { 01234 PRINT_ERROR("In OCCModifyEngine::make_TopoDS_Face\n" 01235 " Cannot find the best fit surface for given curves.\n"); 01236 return (TopoDS_Face*) NULL; 01237 } 01238 01239 return topo_face; 01240 } 01241 //=============================================================================== 01242 // Function : make_Lump 01243 // Member Type: PUBLIC 01244 // Description: make a lump of one shell 01245 // Author : Jane Hu 01246 // Date : 02/08 01247 //=============================================================================== 01248 Lump* OCCModifyEngine::make_Lump( DLIList<Surface*>& surface_list ) const 01249 { 01250 if (surface_list.size() < 2) 01251 return (Lump*) NULL; 01252 01253 //all surfaces should be stand along surface bodies or shell bodies' surface 01254 DLIList<BodySM*> body_list; 01255 for(int i = 0; i < surface_list.size(); i++) 01256 { 01257 OCCSurface* occ_surface = CAST_TO(surface_list.get_and_step(), OCCSurface); 01258 if (occ_surface == NULL) 01259 { 01260 PRINT_ERROR("Cannot create an OCC lump from the given surfaces.\n" 01261 "Possible incompatible geometry engines.\n"); 01262 return (Lump *)NULL; 01263 } 01264 OCCBody* occ_body = occ_surface->my_body(); 01265 if(!occ_body) 01266 { 01267 OCCShell* occ_shell = occ_surface->my_shell(); 01268 if(occ_shell) 01269 occ_body = occ_shell->my_body(); 01270 } 01271 if(!occ_body) 01272 { 01273 DLIList<OCCBody*> original_bodies; 01274 occ_surface->get_bodies(original_bodies); 01275 if(original_bodies.size() > 1) 01276 { 01277 PRINT_ERROR( "Cannot make lump in non-mainfold solids. \n"); 01278 return (Lump*) NULL; 01279 } 01280 else if(original_bodies.size() == 0) 01281 { 01282 PRINT_ERROR( "Interal error: Can't find associated solid. \n"); 01283 return (Lump*) NULL; 01284 } 01285 occ_body = original_bodies.get(); 01286 assert(occ_body != NULL); 01287 } 01288 DLIList<Lump*> lumps; 01289 DLIList<OCCShell*> shells; 01290 DLIList<OCCSurface*> surfaces; 01291 surfaces = occ_body->my_sheet_surfaces(); 01292 shells = occ_body->shells(); 01293 lumps = occ_body->lumps(); 01294 if(lumps.size() > 0 || shells.size() + surfaces.size() > 1) 01295 { 01296 PRINT_ERROR("Cannot create an OCC lump from the given surfaces.\n" 01297 "The surfaces are not free.\n"); 01298 return (Lump *)NULL; 01299 } 01300 body_list.append_unique(occ_body); 01301 } 01302 01303 TopoDS_Shape aShape; 01304 CubitStatus stat = stitch_surfs(body_list, aShape); 01305 if(!stat) 01306 { 01307 PRINT_ERROR("The surfaces are not all connected, can't make a lump. \n"); 01308 return (Lump*)NULL; 01309 } 01310 01311 TopExp_Explorer Ex, Ex2; 01312 TopoDS_Shell aShell ; 01313 for (Ex.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); Ex.More()&& stat; Ex.Next()) 01314 aShell = TopoDS::Shell(Ex.Current()); 01315 01316 //check to make sure the aShell is closed. 01317 int num_edges = 0; 01318 int pairs = 0; 01319 //sometimes there's duplicate TopoDS_Edges in the shell. 01320 DLIList<TopoDS_Edge*> edge_list; 01321 for (Ex.Init(aShell, TopAbs_EDGE); Ex.More()&& stat; Ex.Next()) 01322 { 01323 TopoDS_Edge edge1 = TopoDS::Edge(Ex.Current()); 01324 TopoDS_Edge* new_edge = new TopoDS_Edge(edge1); 01325 edge_list.append(new_edge); 01326 } 01327 01328 int size = edge_list.size(); 01329 for (int i = 0; i < size; i++) 01330 { 01331 TopoDS_Edge edge1 = *edge_list[i]; 01332 int same = 0; 01333 for (int j = i+1; j < edge_list.size(); j++) 01334 { 01335 TopoDS_Edge edge2 = *edge_list[j]; 01336 if(edge1.IsEqual(edge2)) 01337 { 01338 same ++; 01339 edge_list.remove(&edge1); 01340 i--; 01341 size--; 01342 break; 01343 } 01344 } 01345 if(same > 0) 01346 continue; 01347 01348 else 01349 num_edges++; 01350 01351 for (int j = 0; j < size; j++) 01352 { 01353 TopoDS_Edge edge2 = *edge_list[j]; 01354 if (!edge1.IsEqual(edge2)&& edge1.IsSame(edge2)) 01355 { 01356 pairs++; 01357 break; 01358 } 01359 } 01360 } 01361 01362 for (int k = 0; k < edge_list.size(); k++) 01363 { 01364 TopoDS_Edge* edge = edge_list.get_and_step(); 01365 edge->Nullify(); 01366 delete edge; 01367 edge = NULL; 01368 } 01369 01370 if (num_edges == pairs ) 01371 aShell.Closed(CUBIT_TRUE); 01372 01373 else 01374 PRINT_ERROR("Surfaces must make a water-tight shape to make a lump.\n"); 01375 01376 if(aShell.Closed()) 01377 { 01378 BRepBuilderAPI_MakeSolid aMakeSolid(aShell); 01379 if (!aMakeSolid.IsDone()) 01380 { 01381 PRINT_ERROR("Cannot create an OCC Lump from the given surfaces.\n" 01382 "OCC internal error.\n"); 01383 return (Lump *)NULL; 01384 } 01385 01386 TopoDS_Solid aSolid = aMakeSolid.Solid(); 01387 01388 return 01389 OCCQueryEngine::instance()->populate_topology_bridge(aSolid, CUBIT_TRUE); 01390 } 01391 01392 return (Lump*) NULL; 01393 } 01394 01395 //=============================================================================== 01396 // Function : make_BodySM 01397 // Member Type: PUBLIC 01398 // Description: make a BodySM from a surface 01399 // Author : Jane Hu 01400 // Date : 02/08 01401 //=============================================================================== 01402 BodySM* OCCModifyEngine::make_BodySM( Surface *surface ) const 01403 { 01404 OCCSurface* occ_surface = CAST_TO(surface, OCCSurface); 01405 if(!occ_surface) 01406 { 01407 PRINT_ERROR("Cannot create an OCC body from the given surface.\n" 01408 "Possible incompatible geometry engines.\n"); 01409 return (BodySM *)NULL; 01410 } 01411 01412 OCCBody* occ_body = occ_surface->my_body(); 01413 TopoDS_Face* face = occ_surface->get_TopoDS_Face(); 01414 TopoDS_Face newFace; 01415 if(!occ_body) 01416 { 01417 DLIList<OCCBody*> original_bodies; 01418 occ_surface->get_bodies(original_bodies); 01419 if(original_bodies.size() > 0) 01420 occ_body = original_bodies.get(); 01421 } 01422 if(occ_body) 01423 { 01424 //copy the surface to make a sheet body. 01425 BRepBuilderAPI_Copy api_copy(*face); 01426 TopoDS_Shape newShape = api_copy.ModifiedShape(*face); 01427 newFace = TopoDS::Face(newShape); 01428 face = new TopoDS_Face(newFace); 01429 } 01430 01431 surface = OCCQueryEngine::instance()->populate_topology_bridge(*face, CUBIT_TRUE); 01432 01433 return CAST_TO(surface, OCCSurface)->my_body(); 01434 } 01435 01436 01437 01438 //=============================================================================== 01439 // Function : make_BodySM 01440 // Member Type: PUBLIC 01441 // Description: make a BodySM given a list of Lumps. 01442 // Author : Jane Hu 01443 // Date : 02/08 01444 //=============================================================================== 01445 BodySM* OCCModifyEngine::make_BodySM( DLIList<Lump*>& lump_list ) const 01446 { 01447 if (lump_list.size() == 0) 01448 return (BodySM*) NULL; 01449 /* 01450 //Create a compsolid shape, copy all BodySM's solids to create new compbody 01451 DLIList<BodySM*> bodysm_list; 01452 TopoDS_Compound CS; 01453 BRep_Builder B; 01454 B.MakeCompound(CS); 01455 01456 //Add every shape to the CompSolid 01457 for(int i = 0; i < lump_list.size(); i++) 01458 { 01459 Lump* lump = lump_list.get_and_step(); 01460 OCCLump* occ_lump = CAST_TO(lump, OCCLump); 01461 if(!occ_lump) 01462 { 01463 PRINT_ERROR("Cannot create an OCC BodySM from the given lumps.\n" 01464 "Possible incompatible geometry engines.\n"); 01465 return (BodySM *)NULL; 01466 } 01467 TopoDS_Solid* solid = occ_lump->get_TopoDS_Solid(); 01468 BRepBuilderAPI_Copy api_copy(*solid); 01469 TopoDS_Shape newShape = api_copy.ModifiedShape(*solid); 01470 B.Add(CS, newShape); 01471 } 01472 */ 01473 01474 //check if the lumps are already in some bodies, in this case, have to use 01475 //unite operation to create compound. 01476 for (int i = 0 ; i < lump_list.size(); i++) 01477 { 01478 OCCLump* lump = CAST_TO(lump_list.get_and_step(), OCCLump); 01479 if(lump == NULL) 01480 { 01481 PRINT_ERROR("Incompatible engines.\n"); 01482 return (BodySM*) NULL; 01483 } 01484 BodySM* body = lump->get_body(); 01485 if(body != NULL) 01486 OCCQueryEngine::instance()->delete_body(body, CUBIT_FALSE); 01487 } 01488 TopoDS_Compound* Co; 01489 DLIList<OCCShell*> shells; 01490 DLIList<OCCSurface*> surfaces; 01491 Co = OCCBody::make_Compound(lump_list, shells, surfaces); 01492 assert (Co != NULL); 01493 BodySM* bodysm = OCCQueryEngine::instance()->populate_topology_bridge(*Co); 01494 Co->Nullify(); 01495 delete Co; 01496 Co = NULL; 01497 return bodysm; 01498 01499 } 01500 01501 01502 //=============================================================================== 01503 // Function : sphere 01504 // Member Type: PUBLIC 01505 // Description: build an OCC sphere 01506 // Author : Jane Hu 01507 // Date : 03/08 01508 //=============================================================================== 01509 BodySM* OCCModifyEngine::sphere(double radius) const 01510 { 01511 if (radius <= 0) 01512 return (BodySM*) NULL; 01513 01514 TopoDS_Solid S = BRepPrimAPI_MakeSphere(radius); 01515 01516 Lump* lump = OCCQueryEngine::instance()->populate_topology_bridge(S, 01517 CUBIT_TRUE); 01518 if (lump == NULL) 01519 return (BodySM*)NULL; 01520 01521 return CAST_TO(lump, OCCLump)->get_body(); 01522 } 01523 01524 01525 //=============================================================================== 01526 // Function : brick 01527 // Member Type: PUBLIC 01528 // Description: build an OCC brick 01529 // Author : Jane Hu 01530 // Date : 03/08 01531 //=============================================================================== 01532 BodySM* OCCModifyEngine::brick( double wid, double dep, double hi ) const 01533 { 01534 if (wid <= 0 || dep <=0 || hi <= 0) 01535 return (BodySM*)NULL; 01536 01537 TopoDS_Solid S = BRepPrimAPI_MakeBox(wid, dep, hi); 01538 01539 Lump* lump = OCCQueryEngine::instance()->populate_topology_bridge(S, 01540 CUBIT_TRUE); 01541 01542 if (lump == NULL) 01543 return (BodySM*)NULL; 01544 01545 BodySM* body = CAST_TO(lump, OCCLump)->get_body(); 01546 if(body) 01547 CAST_TO(body,OCCBody)->move(-wid/2.0, -dep/2.0, -hi/2.0); 01548 return body; 01549 } 01550 01551 01552 //=============================================================================== 01553 // Function : brick 01554 // Member Type: PUBLIC 01555 // Description: create an OCC brick given center axes and extension 01556 // extension is equvlent to (wid/2, dep/2, hi/2) 01557 // center should be given the coordinates in global system 01558 // Author : Jane Hu 01559 // Date : 03/08 01560 //=============================================================================== 01561 BodySM* OCCModifyEngine::brick( const CubitVector& center, 01562 const CubitVector axes[3], 01563 const CubitVector &extension) const 01564 { 01565 gp_Pnt left_point(0,0,0); 01566 gp_Dir main_dir(axes[2].x(), axes[2].y(), axes[2].z()); 01567 gp_Dir x_dir(axes[0].x(), axes[0].y(), axes[0].z()); 01568 gp_Ax2 Axis(left_point, main_dir, x_dir); 01569 TopoDS_Solid S = BRepPrimAPI_MakeBox( Axis, extension.x()*2, extension.y()*2, 01570 extension.z()*2); 01571 01572 Lump* lump = OCCQueryEngine::instance()->populate_topology_bridge(S, 01573 CUBIT_TRUE); 01574 if (lump == NULL) 01575 return (BodySM*)NULL; 01576 01577 BodySM* body = CAST_TO(lump, OCCLump)->get_body(); 01578 if(body) 01579 { 01580 CubitVector center_point; 01581 double volume; 01582 OCCBody* occ_body = CAST_TO(body,OCCBody); 01583 occ_body->mass_properties(center_point, volume); 01584 CubitVector move_vec = center - center_point; 01585 occ_body->move(move_vec.x(), move_vec.y(), move_vec.z()); 01586 return body; 01587 } 01588 return (BodySM*)NULL; 01589 } 01590 01591 //=============================================================================== 01592 // Function : prism 01593 // Member Type: PUBLIC 01594 // Description: create an OCC prism 01595 // Author : Jane Hu 01596 // Date : 03/08 01597 //=============================================================================== 01598 BodySM* OCCModifyEngine::prism( double height, int sides, double major, 01599 double minor) const 01600 { 01601 if(major <= 0. || minor <= 0. || (major - minor) <= -TOL) 01602 { 01603 PRINT_ERROR("Major and minor radii must be greater than zero.\n"); 01604 return (BodySM*)NULL; 01605 } 01606 01607 if (sides == 4) 01608 return brick(2 * major, 2 * minor, height); 01609 01610 TopoDS_Wire wire ; 01611 make_base_for_prim_pyramid(major, minor, height, sides, wire); 01612 01613 TopoDS_Face base = BRepBuilderAPI_MakeFace(wire, Standard_True); 01614 gp_Dir main_dir(0.0, 0.0, 1.0); 01615 gp_Vec norm(main_dir); 01616 norm *= height; 01617 BRepSweep_Prism swept(base, norm); 01618 TopoDS_Shape new_shape = swept.Shape(); 01619 DLIList<TopologyBridge*> tbs; 01620 tbs += OCCQueryEngine::instance()->populate_topology_bridge(new_shape); 01621 assert(tbs.size() == 1); 01622 01623 BodySM* bodysm = CAST_TO(tbs.get(), BodySM); 01624 return bodysm; 01625 } 01626 01627 void OCCModifyEngine::make_base_for_prim_pyramid(double major, 01628 double minor, 01629 double height, 01630 int sides, 01631 TopoDS_Wire& wire)const 01632 { 01633 //One of the polygon side will be perpendicular to positive x-axis. 01634 double y = major * sin(CUBIT_PI/sides); 01635 double x = sqrt(major * major - y * y); 01636 gp_Pnt start(x, y, -height/2.0); 01637 01638 DLIList<gp_Pnt> point_list; 01639 double theta = 2.0/sides*CUBIT_PI; 01640 for(int n =1 ; n < sides; n++) 01641 { 01642 double angle = theta * (n + 0.5); 01643 gp_Pnt v(major * cos(angle), major * sin(angle), -height/2.0); 01644 point_list.append(v); 01645 } 01646 01647 TopoDS_Edge new_edge; 01648 BRepBuilderAPI_MakePolygon poly_maker; 01649 gp_Dir main_dir(0.0, 0.0, 1.0); 01650 point_list.append(start); 01651 01652 if (fabs(major - minor) < TOL) 01653 for (int i = 0; i <sides; i++) 01654 poly_maker.Add(point_list[i]); 01655 else 01656 { 01657 for (int i = 0; i <sides; i++) 01658 { 01659 x = point_list[i].X(); 01660 if((y=point_list[i].Y()) > 0.0) 01661 y = sqrt((1-x*x/major/major)*minor*minor); 01662 else 01663 y = -sqrt((1-x*x/major/major)*minor*minor); 01664 point_list[i].SetY(y); 01665 poly_maker.Add(point_list[i]); 01666 } 01667 } 01668 poly_maker.Close(); 01669 01670 wire = poly_maker.Wire(); 01671 } 01672 01673 //=============================================================================== 01674 // Function : pyramid 01675 // Member Type: PUBLIC 01676 // Description: create an OCC pyramid 01677 // Author : Jane Hu 01678 // Date : 03/08 01679 //=============================================================================== 01680 BodySM* OCCModifyEngine::pyramid( double height, int sides, double major, 01681 double minor, double top) const 01682 { 01683 TopoDS_Solid S; 01684 01685 //build the top and bottom shapes. 01686 TopoDS_Wire wire_bottom ; 01687 make_base_for_prim_pyramid(major, minor, height, sides, wire_bottom); 01688 double top_minor = top * minor / major; 01689 TopoDS_Wire wire_top ; 01690 BRepOffsetAPI_ThruSections builder(CUBIT_TRUE, CUBIT_TRUE); 01691 builder.AddWire(wire_bottom); 01692 if(top > TOL) 01693 { 01694 make_base_for_prim_pyramid(top, top_minor, -height, sides, wire_top); 01695 builder.AddWire(wire_top); 01696 } 01697 else 01698 { 01699 gp_Pnt pt = gp_Pnt( 0.0, 0.0, height/2.0); 01700 TopoDS_Vertex theVertex = BRepBuilderAPI_MakeVertex(pt); 01701 builder.AddVertex(theVertex); 01702 } 01703 builder.Build() ; 01704 S = TopoDS::Solid(builder.Shape()); 01705 01706 Lump* lump = OCCQueryEngine::instance()->populate_topology_bridge(S, 01707 CUBIT_TRUE); 01708 if (lump == NULL) 01709 return (BodySM*)NULL; 01710 01711 BodySM* body = CAST_TO(lump, OCCLump)->get_body(); 01712 return body; 01713 01714 } 01715 01716 //=============================================================================== 01717 // Function : cylinder 01718 // Member Type: PUBLIC 01719 // Description: create an OCC cylinder, its base shape can be ellipse with 01720 // r1, r2 while r3 = 0; or it can be a cone with r1, 01721 // r3 while r2 = 0. 01722 // Author : Jane Hu 01723 // Date : 03/08 01724 //=============================================================================== 01725 BodySM* OCCModifyEngine::cylinder( double hi, double r1, double r2, double r3 ) const 01726 { 01727 TopoDS_Solid S; 01728 if(r2 != r1)//elliptical based cylinder 01729 { 01730 gp_Pnt center(0.0, 0.0, 0.0); 01731 gp_Dir main_dir(0.0, 0.0, 1.0); 01732 gp_Dir x_dir(1.0, 0.0, 0.0); 01733 gp_Ax2 Axis(center, main_dir, x_dir); 01734 if(r1 < r2) 01735 { 01736 double temp_r = r1; 01737 r1 = r2; 01738 r2 = temp_r; 01739 } 01740 Handle(Geom_Curve) curve_ptr = GC_MakeEllipse(Axis, r1, r2); 01741 TopoDS_Edge new_edge = BRepBuilderAPI_MakeEdge(curve_ptr); 01742 BRepBuilderAPI_MakeWire aWire(new_edge); 01743 01744 TopoDS_Wire test_Wire = aWire.Wire(); 01745 01746 BRepOffsetAPI_ThruSections builder(CUBIT_TRUE, CUBIT_TRUE); 01747 builder.AddWire(test_Wire); 01748 if (r3 == 0) 01749 { 01750 gp_Pnt pt = gp_Pnt( 0.0, 0.0, hi); 01751 TopoDS_Vertex theVertex = BRepBuilderAPI_MakeVertex(pt); 01752 builder.AddVertex(theVertex); 01753 } 01754 else 01755 { 01756 gp_Pnt center2(0.0, 0.0,hi); 01757 gp_Ax2 Axis2(center2, main_dir, x_dir); 01758 Handle(Geom_Curve) curve_ptr = GC_MakeEllipse(Axis2, r3, r3*r2/r1); 01759 TopoDS_Edge new_edge = BRepBuilderAPI_MakeEdge(curve_ptr); 01760 BRepBuilderAPI_MakeWire aWire(new_edge); 01761 TopoDS_Wire test_Wire = aWire.Wire(); 01762 builder.AddWire(test_Wire); 01763 } 01764 builder.Build() ; 01765 S = TopoDS::Solid(builder.Shape()); 01766 } 01767 01768 else // cone 01769 { 01770 if(r1 == r3) //cylinder 01771 S = BRepPrimAPI_MakeCylinder(r1, hi); 01772 else 01773 S = BRepPrimAPI_MakeCone(r1, r3, hi); 01774 } 01775 01776 Lump* lump = OCCQueryEngine::instance()->populate_topology_bridge(S, 01777 CUBIT_TRUE); 01778 01779 if (lump == NULL) 01780 { 01781 PRINT_ERROR("In OCCModifyEngine::cylinder\n" 01782 " Cannot create a cylinder for given radii.\n"); 01783 return (BodySM*)NULL; 01784 } 01785 01786 BodySM* body = CAST_TO(lump, OCCLump)->get_body(); 01787 if(body) 01788 CAST_TO(body, OCCBody)->move(0, 0, -hi/2.0); 01789 return body; 01790 } 01791 01792 //=============================================================================== 01793 // Function : torus 01794 // Member Type: PUBLIC 01795 // Description: create an OCC torus 01796 // Author : Jane Hu 01797 // Date : 03/08 01798 //=============================================================================== 01799 BodySM* OCCModifyEngine::torus( double r1, double r2 ) const 01800 { 01801 if (r1 <= 0 || r2 <= 0) 01802 return (BodySM*) NULL; 01803 01804 TopoDS_Solid S = BRepPrimAPI_MakeTorus(r1, r2); 01805 01806 Lump* lump = OCCQueryEngine::instance()->populate_topology_bridge(S, 01807 CUBIT_TRUE); 01808 01809 if (lump == NULL) 01810 { 01811 PRINT_ERROR("In OCCModifyEngine::torus\n" 01812 " Cannot create a torus for given radii.\n"); 01813 return (BodySM*)NULL; 01814 } 01815 01816 return CAST_TO(lump, OCCLump)->get_body(); 01817 } 01818 01819 //=============================================================================== 01820 // Function : planar_sheet 01821 // Member Type: PUBLIC 01822 // Description: create an OCC planar_sheet with four vectors. 01823 // Author : Jane Hu 01824 // Date : 03/08 01825 //=============================================================================== 01826 BodySM* OCCModifyEngine::planar_sheet ( const CubitVector& p1, 01827 const CubitVector& p2, 01828 const CubitVector& p3, 01829 const CubitVector& p4) const 01830 { 01831 TBPoint* point1 = make_Point(p1); 01832 TBPoint* point2 = make_Point(p2); 01833 TBPoint* point3 = make_Point(p3); 01834 TBPoint* point4 = make_Point(p4); 01835 Curve * curve1 = make_Curve( point1, point2); 01836 if (curve1 == NULL) 01837 return (BodySM*) NULL; 01838 Curve * curve2 = make_Curve( point2, point3); 01839 if (curve2 == NULL) 01840 return (BodySM*) NULL; 01841 Curve * curve3 = make_Curve( point3, point4); 01842 if (curve3 == NULL) 01843 return (BodySM*) NULL; 01844 Curve * curve4 = make_Curve( point4, point1); 01845 if (curve4 == NULL) 01846 return (BodySM*) NULL; 01847 DLIList<Curve*> curves; 01848 curves.append(curve1); 01849 curves.append(curve2); 01850 curves.append(curve3); 01851 curves.append(curve4); 01852 Surface* surface = make_Surface(PLANE_SURFACE_TYPE, curves); 01853 if (surface == NULL) 01854 return (BodySM*) NULL; 01855 01856 return CAST_TO(surface,OCCSurface)->my_body(); 01857 } 01858 01859 //=============================================================================== 01860 // Function : copy_body 01861 // Member Type: PUBLIC 01862 // Description: copy an OCC-based body 01863 // Author : Jane Hu 01864 // Date : 03/08 01865 //=============================================================================== 01866 BodySM* OCCModifyEngine::copy_body ( BodySM* bodyPtr, std::map<TopologyBridge*, TopologyBridge*> * /*old_tb_to_new_tb*/ ) const 01867 { 01868 BodySM* new_body = NULL; 01869 OCCBody* occ_body = CAST_TO(bodyPtr, OCCBody); 01870 if (!occ_body) 01871 { 01872 PRINT_ERROR("Cannot create an OCC bodySM from the given bodySM.\n" 01873 "Possible incompatible geometry engines.\n"); 01874 return (BodySM *)NULL; 01875 } 01876 01877 DLIList<CubitSimpleAttrib> list; 01878 TopoDS_Compound *theCS = occ_body->get_TopoDS_Shape(); 01879 01880 if (theCS == NULL) //single lump or shell or surface body 01881 { 01882 DLIList<OCCShell*> shells = occ_body->shells(); 01883 assert(shells.size() < 2); 01884 for(int i = 0 ; i < shells.size(); i++) 01885 { 01886 TopoDS_Shell* shell = shells.get_and_step()->get_TopoDS_Shell(); 01887 BRepBuilderAPI_Copy api_copy(*shell); 01888 TopoDS_Shape newShape = api_copy.ModifiedShape(*shell); 01889 TopoDS_Shell newShell = TopoDS::Shell(newShape); 01890 new_body = OCCQueryEngine::instance()->populate_topology_bridge(newShell, CUBIT_TRUE)->my_body(); 01891 copy_body_attributes((TopoDS_Shape)(*shell), api_copy); 01892 } 01893 01894 DLIList<OCCSurface*> surfaces = occ_body->my_sheet_surfaces(); 01895 assert(surfaces.size() < 2); 01896 01897 for(int i = 0 ; !new_body && i < surfaces.size(); i++) 01898 { 01899 OCCSurface *occ_surface = CAST_TO(surfaces.get_and_step(), OCCSurface); 01900 TopoDS_Face *theFace = occ_surface->get_TopoDS_Face(); 01901 BRepBuilderAPI_Copy api_copy(*theFace); 01902 TopoDS_Shape newShape = api_copy.ModifiedShape(*theFace); 01903 TopoDS_Face newFace = TopoDS::Face(newShape); 01904 Surface* surface = OCCQueryEngine::instance()->populate_topology_bridge( 01905 newFace, CUBIT_TRUE ); 01906 OCCSurface* occ_surf = CAST_TO(surface, OCCSurface); 01907 new_body = occ_surf->my_body(); 01908 copy_body_attributes((TopoDS_Shape)(*theFace) , api_copy); 01909 } 01910 01911 //single lump body 01912 if (!new_body) 01913 { 01914 Lump *lump = occ_body->lumps().get(); 01915 TopoDS_Solid solid = *(CAST_TO(lump, OCCLump)->get_TopoDS_Solid()); 01916 BRepBuilderAPI_Copy api_copy(solid); 01917 TopoDS_Shape newShape = api_copy.ModifiedShape(solid); 01918 TopoDS_Solid newSolid = TopoDS::Solid(newShape); 01919 lump = OCCQueryEngine::instance()->populate_topology_bridge(newSolid, 01920 CUBIT_TRUE); 01921 01922 new_body = CAST_TO(lump, OCCLump)->get_body(); 01923 copy_body_attributes((TopoDS_Shape)solid, api_copy); 01924 } 01925 } 01926 01927 if(!new_body && theCS && !theCS->IsNull() && 01928 OCCQueryEngine::instance()->OCCMap->IsBound(*theCS)) 01929 { 01930 BRepBuilderAPI_Copy api_copy(*theCS); 01931 01932 TopoDS_Shape newShape = api_copy.ModifiedShape(*theCS); 01933 01934 TopoDS_Compound newCS = TopoDS::Compound(newShape); 01935 01936 new_body = OCCQueryEngine::instance()->populate_topology_bridge(newCS); 01937 copy_body_attributes((TopoDS_Shape)(*theCS), api_copy); 01938 OCCAttribSet::get_attributes(newCS, list); 01939 for(int kk = 0; kk < list.size(); kk++) 01940 new_body->append_simple_attribute_virt(list.get_and_step()); 01941 } 01942 01943 return new_body; 01944 } 01945 01946 BodySM* OCCModifyEngine::create_body( VolumeFacets& volume, 01947 std::map<FacetShapes*, GeometryEntity*>& entity_map, 01948 const FacetPointSet& points, 01949 int interp_order) const 01950 { 01951 return (BodySM*) NULL; 01952 } 01953 01954 CubitStatus OCCModifyEngine::copy_body_attributes(TopoDS_Shape orig_shape, 01955 BRepBuilderAPI_Copy& api_copy)const 01956 { 01957 DLIList<CubitSimpleAttrib> list; 01958 TopTools_IndexedMapOfShape M; 01959 TopExp::MapShapes(orig_shape, TopAbs_SOLID, M); 01960 for(int ii=1; ii<=M.Extent(); ii++) 01961 { 01962 TopoDS_Solid solid = TopoDS::Solid(M(ii)); 01963 TopoDS_Solid new_solid = TopoDS::Solid(api_copy.ModifiedShape(solid)); 01964 if(!new_solid.IsNull()) 01965 OCCQueryEngine::instance()->copy_attributes(solid, new_solid); 01966 list.clean_out(); 01967 OCCAttribSet::get_attributes(new_solid,list); 01968 OCCLump *lump = NULL; 01969 int k = OCCQueryEngine::instance()->OCCMap->Find(new_solid); 01970 lump = (OCCLump*) (OCCQueryEngine::instance()->OccToCGM->find(k))->second; 01971 for(int kk = 0; kk < list.size(); kk++) 01972 lump->append_simple_attribute_virt(list.get_and_step()); 01973 01974 if (list.size() == 0) 01975 { 01976 k = OCCQueryEngine::instance()->OCCMap->Find(solid); 01977 OCCLump *orig_lump = (OCCLump*) (OCCQueryEngine::instance()->OccToCGM->find(k))->second; 01978 OCCBody* body = (OCCBody*)orig_lump->get_body(); 01979 if(body) 01980 { 01981 body->get_simple_attribute(list); 01982 for (int kk = 0; kk < list.size(); kk++) 01983 lump->get_body()->append_simple_attribute_virt(list.get_and_step()); 01984 } 01985 } 01986 } 01987 01988 M.Clear(); 01989 TopExp::MapShapes(orig_shape, TopAbs_FACE, M); 01990 for(int ii=1; ii<=M.Extent(); ii++) 01991 { 01992 TopoDS_Face face = TopoDS::Face(M(ii)); 01993 TopoDS_Face new_face = TopoDS::Face(api_copy.ModifiedShape(face)); 01994 if(!new_face.IsNull()) 01995 OCCQueryEngine::instance()->copy_attributes(face, new_face); 01996 list.clean_out(); 01997 OCCAttribSet::get_attributes(new_face, list); 01998 OCCSurface* surf = NULL; 01999 int k = OCCQueryEngine::instance()->OCCMap->Find(new_face); 02000 surf = (OCCSurface*)(OCCQueryEngine::instance()->OccToCGM->find(k))->second; 02001 for(int kk = 0; kk < list.size(); kk++) 02002 surf->append_simple_attribute_virt(list.get_and_step()); 02003 02004 if(list.size() == 0) 02005 { 02006 k = OCCQueryEngine::instance()->OCCMap->Find(orig_shape); 02007 OCCBody* body = NULL; 02008 if(orig_shape.ShapeType() == TopAbs_FACE) 02009 { 02010 OCCSurface *orig_surf = (OCCSurface*) (OCCQueryEngine::instance()->OccToCGM->find(k))->second; 02011 body = orig_surf->my_body(); 02012 } 02013 else if(orig_shape.ShapeType() == TopAbs_SHELL) 02014 { 02015 OCCShell* orig_shell = (OCCShell*) (OCCQueryEngine::instance()->OccToCGM->find(k))->second; 02016 body = orig_shell->my_body(); 02017 } 02018 //Solid and Compound case has been considered in the above cases. 02019 if(body) 02020 { 02021 body->get_simple_attribute(list); 02022 for (int kk = 0; kk < list.size(); kk++) 02023 surf->my_body()->append_simple_attribute_virt(list.get_and_step()); 02024 } 02025 } 02026 } 02027 02028 M.Clear(); 02029 TopExp::MapShapes(orig_shape, TopAbs_EDGE, M); 02030 for(int ii=1; ii<=M.Extent(); ii++) 02031 { 02032 TopoDS_Edge edge = TopoDS::Edge(M(ii)); 02033 TopoDS_Edge new_edge = TopoDS::Edge(api_copy.ModifiedShape(edge)); 02034 if(!new_edge.IsNull()) 02035 OCCQueryEngine::instance()->copy_attributes(edge, new_edge); 02036 list.clean_out(); 02037 OCCAttribSet::get_attributes(new_edge, list); 02038 if(list.size() > 0) 02039 { 02040 int k = OCCQueryEngine::instance()->OCCMap->Find(new_edge); 02041 OCCCurve* curve = (OCCCurve*) (OCCQueryEngine::instance()->OccToCGM->find(k))->second; 02042 for(int kk = 0; kk < list.size(); kk++) 02043 curve->append_simple_attribute_virt(list.get_and_step()); 02044 } 02045 } 02046 02047 M.Clear(); 02048 TopExp::MapShapes(orig_shape, TopAbs_VERTEX, M); 02049 for(int ii=1; ii<=M.Extent(); ii++) 02050 { 02051 TopoDS_Vertex vertex = TopoDS::Vertex(M(ii)); 02052 TopoDS_Vertex new_vertex = TopoDS::Vertex(api_copy.ModifiedShape(vertex)); 02053 if(!new_vertex.IsNull()) 02054 OCCQueryEngine::instance()->copy_attributes(vertex, new_vertex); 02055 list.clean_out(); 02056 OCCAttribSet::get_attributes(new_vertex, list); 02057 if(list.size() > 0) 02058 { 02059 int k = OCCQueryEngine::instance()->OCCMap->Find(new_vertex); 02060 OCCPoint* point = (OCCPoint*) (OCCQueryEngine::instance()->OccToCGM->find(k))->second; 02061 for(int kk = 0; kk < list.size(); kk++) 02062 point->append_simple_attribute_virt(list.get_and_step()); 02063 } 02064 } 02065 return CUBIT_SUCCESS; 02066 } 02067 //=============================================================================== 02068 // Function : stitch 02069 // Member Type: PUBLIC 02070 // Description: stitch all surfs and try to make a shell body. 02071 // tighten_gaps and tolerance are not used here. 02072 // Author : Jane Hu 02073 // Date : 03/08 02074 //=============================================================================== 02075 CubitStatus OCCModifyEngine::stitch( 02076 DLIList<BodySM*>& surf_bodies, 02077 DLIList<BodySM*> &new_bodies, 02078 bool tighten_gaps, 02079 double tolerance) const 02080 { 02081 if (surf_bodies.size()==0) 02082 return CUBIT_SUCCESS; 02083 02084 if (surf_bodies.size()==1) 02085 { 02086 new_bodies = surf_bodies; 02087 return CUBIT_SUCCESS; 02088 } 02089 02090 TopoDS_Shape fuse; 02091 CubitStatus stat = stitch_surfs(surf_bodies, fuse); 02092 02093 TopExp_Explorer Ex; 02094 DLIList<TopologyBridge*> tbs; 02095 for (Ex.Init(fuse, TopAbs_SHELL, TopAbs_SOLID); Ex.More(); Ex.Next()) 02096 { 02097 TopoDS_Shape shape = Ex.Current(); 02098 tbs += OCCQueryEngine::instance()->populate_topology_bridge(shape); 02099 } 02100 02101 if (stat) 02102 { 02103 BodySM* body = CAST_TO(tbs.get(), BodySM); 02104 new_bodies.append(body); 02105 } 02106 02107 else 02108 { 02109 for(int i= 0; i<tbs.size(); i++) 02110 new_bodies.append(CAST_TO(tbs.get_and_step(), OCCBody)); 02111 } 02112 02113 PRINT_WARNING("Occ engine doesn't consider tighten_gaps and tolerance in stitch operation. \n"); 02114 return CUBIT_SUCCESS; 02115 } 02116 02117 //=============================================================================== 02118 // Function : stitch_surfs 02119 // Member Type: PUBLIC 02120 // Description: stitch all surfs and try to make a TopoDS_Shell . 02121 // called by stitch into surface body 02122 // Author : Jane Hu 02123 // Date : 03/08 02124 //=============================================================================== 02125 CubitStatus OCCModifyEngine::stitch_surfs( 02126 DLIList<BodySM*>& surf_bodies, 02127 TopoDS_Shape& fuse) const 02128 { 02129 if (surf_bodies.size() < 2) 02130 return CUBIT_SUCCESS; 02131 02132 DLIList<TopoDS_Shape*> faces_to_stitch; 02133 DLIList<OCCSurface*> original_surfaces; 02134 for (int i = 0; i < surf_bodies.size(); i++) 02135 { 02136 BodySM * tool_body = surf_bodies.get_and_step(); 02137 OCCBody* occ_body = CAST_TO(tool_body, OCCBody); 02138 DLIList<OCCSurface*> surfaces = occ_body->my_sheet_surfaces(); 02139 DLIList<OCCShell*> shells = occ_body->shells(); 02140 DLIList<Lump*> lumps = occ_body->lumps(); 02141 if (surfaces.size()+shells.size() != 1 || lumps.size() > 0) 02142 { 02143 PRINT_ERROR("Can't stitch non-sheet bodySM's. \n"); 02144 return CUBIT_FAILURE; 02145 } 02146 02147 original_surfaces += surfaces; 02148 delete occ_body; 02149 OCCQueryEngine::instance()->BodyList->remove(occ_body); 02150 if (surfaces.size() == 1) 02151 { 02152 OCCSurface* surface = surfaces.get(); 02153 delete surface->my_shell(); 02154 delete surface->my_lump(); 02155 surface->set_shell(NULL); 02156 surface->set_lump(NULL); 02157 surface->set_body(NULL); 02158 02159 TopoDS_Face* topods_face = surface->get_TopoDS_Face(); 02160 if (topods_face != NULL) 02161 faces_to_stitch.append(topods_face); 02162 } 02163 else 02164 { 02165 OCCShell* shell = shells.get(); 02166 delete shell->my_lump(); 02167 shell->set_body(NULL); 02168 shell->set_lump(NULL); 02169 02170 TopoDS_Shell* topods_shell = shell->get_TopoDS_Shell(); 02171 if(topods_shell) 02172 faces_to_stitch.append(topods_shell); 02173 } 02174 } 02175 02176 faces_to_stitch.reset(); 02177 02178 BRepBuilderAPI_Sewing sew; 02179 02180 for( int i = faces_to_stitch.size()-1; i >= 0; i --) 02181 { 02182 TopoDS_Shape* face = faces_to_stitch[i]; 02183 sew.Add(*face); 02184 } 02185 02186 sew.Perform(); 02187 TopoDS_Shape sewn_shape=sew.SewedShape(); 02188 02189 fuse=sewn_shape; 02190 02191 TopExp_Explorer Ex; 02192 int count_shell = 0; 02193 for (Ex.Init(fuse, TopAbs_SHELL, TopAbs_SOLID); Ex.More(); Ex.Next()) 02194 count_shell++; 02195 02196 if ( count_shell != 1) 02197 { 02198 PRINT_ERROR("Can't stitch all surfaces into one BodySM's. \n"); 02199 return CUBIT_FAILURE; 02200 } 02201 02202 for( int i = original_surfaces.size()-1; i >= 0; i --) 02203 OCCQueryEngine::instance()-> 02204 delete_solid_model_entities( (Surface*)original_surfaces.pop()); 02205 02206 return CUBIT_SUCCESS; 02207 } 02208 02209 //=============================================================================== 02210 // Function : subtract 02211 // Member Type: PUBLIC 02212 // Description: subtract boolean operation on OCC-based bodies 02213 // Author : Jane Hu 02214 // Date : 03/08 02215 //=============================================================================== 02216 CubitStatus OCCModifyEngine::subtract(DLIList<BodySM*> &tool_body_list, 02217 DLIList<BodySM*> &from_bodies, 02218 DLIList<BodySM*> &new_bodies, 02219 bool imprint, 02220 bool keep_old) const 02221 { 02222 // copy the bodies in case keep_old is true 02223 DLIList<TopoDS_Shape*> tool_bodies_copy; 02224 02225 //for subtract function, tool-body has to be solid, 02226 //otherwise it's just imprint 02227 DLIList<CubitBox*>* tool_boxes = new DLIList<CubitBox*>(); 02228 DLIList<CubitBoolean> is_tool_volume; 02229 //keep the tool_body untouched 02230 CubitStatus stat = 02231 get_shape_list(tool_body_list, tool_bodies_copy, is_tool_volume, CUBIT_TRUE, tool_boxes); 02232 02233 if(!stat) 02234 return stat; 02235 02236 stat = do_subtract(from_bodies, tool_bodies_copy, is_tool_volume, 02237 tool_boxes, new_bodies, keep_old, imprint) ; 02238 02239 //ok, we're done with all cuts, delete unnecessaries. 02240 CubitBoolean delete_tool_boxes = CUBIT_FALSE; 02241 if(tool_boxes->size() > 0) 02242 delete_tool_boxes = CUBIT_TRUE; 02243 while (tool_boxes->size()) 02244 delete tool_boxes->pop(); 02245 if(delete_tool_boxes) 02246 delete tool_boxes; 02247 while (tool_bodies_copy.size()) 02248 delete tool_bodies_copy.pop(); 02249 if(!keep_old) //delete tool_bodies 02250 OCCQueryEngine::instance()->delete_solid_model_entities(tool_body_list); 02251 return stat; 02252 } 02253 02254 CubitStatus OCCModifyEngine::do_subtract(DLIList<BodySM*> &from_bodies, 02255 DLIList<TopoDS_Shape*> &tool_bodies_copy, 02256 DLIList<CubitBoolean> &is_tool_volume, 02257 DLIList<CubitBox*>* tool_boxes, 02258 DLIList<BodySM*> &new_bodies, 02259 bool keep_old, 02260 bool imprint) const 02261 { 02262 DLIList<TopoDS_Shape*> from_bodies_copy; 02263 DLIList<CubitBoolean> is_volume; 02264 //get the from_bodies underling shapes 02265 CubitStatus stat = get_shape_list(from_bodies, from_bodies_copy, is_volume, keep_old); 02266 if(!stat) 02267 { 02268 for (int i = 0; i < tool_bodies_copy.size(); i++) 02269 { 02270 TopoDS_Shape* shape = tool_bodies_copy.get_and_step(); 02271 delete shape; 02272 shape = NULL; 02273 } 02274 tool_bodies_copy.clean_out(); 02275 return CUBIT_FAILURE; 02276 } 02277 02278 //check that tool_bodies are all solid, shell and surface body can't be used 02279 //for subtracting solids. 02280 if(is_tool_volume.is_in_list(CUBIT_FALSE) && !is_volume.is_in_list(CUBIT_FALSE)) 02281 { 02282 PRINT_WARNING("Surfaces or Shells can't be used to cut a solid.\n"); 02283 while (tool_bodies_copy.size()) 02284 delete tool_bodies_copy.pop(); 02285 while (from_bodies_copy.size()) 02286 delete from_bodies_copy.pop(); 02287 return CUBIT_FAILURE; 02288 } 02289 02290 int fraction_remaining = 100; 02291 02292 // subtract the tool body from each body in the list 02293 02294 TopoDS_Shape* from_shape = from_bodies_copy.get(); 02295 DLIList<TopologyBridge*> tbs; 02296 for (int i = 0; i < from_bodies_copy.size(); i++) 02297 { 02298 CubitBoolean from_volume = is_volume.get_and_step(); 02299 BodySM* from_body = from_bodies.get(); 02300 CubitBox box1 = CAST_TO(from_body, OCCBody)->get_bounding_box(); 02301 int count = 0; //count for not preforming cut 02302 for(int j = 0; j < tool_bodies_copy.size(); j ++) 02303 { 02304 CubitBoolean tool_volume = is_tool_volume.get_and_step(); 02305 if(tool_volume == CUBIT_FALSE && from_volume == CUBIT_TRUE) 02306 { 02307 PRINT_WARNING("Surfaces or Shells can't be used to cut a solid.\n"); 02308 continue; 02309 } 02310 if (AppUtil::instance()->interrupt()) 02311 { 02312 PRINT_ERROR("Subtraction interrupted. Aborting...\n"); 02313 while (tool_bodies_copy.size()) 02314 delete tool_bodies_copy.pop(); 02315 while (from_bodies_copy.size()) 02316 delete from_bodies_copy.pop(); 02317 return CUBIT_FAILURE; 02318 } 02319 CubitBox tool_box = *tool_boxes->get_and_step(); 02320 if(!tool_box.overlap(TOL,box1)) 02321 { 02322 count++; 02323 continue; 02324 } 02325 TopoDS_Shape* tool_shape = tool_bodies_copy.get_and_step(); 02326 02327 //bodies overlap, proceed with the subtract 02328 BRepAlgoAPI_Cut cutter(*from_shape, *tool_shape); 02329 TopoDS_Shape cut_shape = cutter.Shape(); 02330 02331 //compare to see if the from_shape has gotten cut. 02332 CubitBoolean has_changed = CUBIT_FALSE; 02333 double after_mass = 0.0; 02334 GProp_GProps myProps; 02335 if(is_volume[i]) 02336 BRepGProp::VolumeProperties(cut_shape, myProps); 02337 02338 else 02339 BRepGProp::SurfaceProperties(cut_shape, myProps); 02340 after_mass = myProps.Mass(); 02341 if(after_mass > TOL) 02342 check_operation(cut_shape, from_shape, is_volume[i], has_changed, 02343 &cutter, keep_old); 02344 else 02345 { 02346 /* 02347 if(!keep_old) 02348 OCCQueryEngine::instance()->delete_solid_model_entities(from_body); 02349 from_shape->Nullify(); 02350 */ 02351 from_shape = NULL; 02352 } 02353 02354 int stat; 02355 if(!has_changed && from_shape && !from_shape->IsNull()) 02356 { 02357 //Add imprint code here 02358 DLIList<TopoDS_Face*> face_list; 02359 if(imprint) 02360 { 02361 stat = imprint_toposhapes(from_shape, tool_shape, face_list); 02362 if(stat) 02363 { 02364 PRINT_ERROR("Can't do imprint operation on the body. \n"); 02365 count++; 02366 } 02367 continue; 02368 } 02369 } 02370 } 02371 02372 //ok, we're done with all cuts, construct new Body' 02373 if (count < tool_bodies_copy.size() && from_shape && !from_shape->IsNull()) 02374 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*from_shape); 02375 else if (from_shape && !from_shape->IsNull()) 02376 { 02377 PRINT_INFO("The %d body did not change because cutting tools are not interscting with it.\n", i+1); 02378 from_bodies.change_to(NULL); 02379 } 02380 from_bodies.step(); 02381 from_shape = from_bodies_copy.step_and_get(); 02382 02383 // done with this j iteration; write out count, if necessary 02384 if (from_bodies.size() * tool_bodies_copy.size() > 1) 02385 { 02386 int frac_done = (100 * (i+1)) / (from_bodies.size()); 02387 if ((100 - frac_done) < fraction_remaining) 02388 { 02389 fraction_remaining = 100 - frac_done; 02390 PRINT_INFO("%d%% remaining.\n ", fraction_remaining+1); 02391 } 02392 } 02393 } 02394 02395 for (int i = 0; i< tbs.size(); i++) 02396 { 02397 BodySM* bodysm = CAST_TO(tbs.get_and_step(), BodySM); 02398 if (bodysm) 02399 new_bodies.append(bodysm); 02400 } 02401 02402 //ok, we're done with all cuts, delete unnecessaries. 02403 if(keep_old) 02404 { 02405 int size = from_bodies_copy.size(); 02406 for (int i = 0; i < size; i++) 02407 { 02408 TopoDS_Shape* shape = from_bodies_copy.pop(); 02409 if(shape != NULL ) 02410 { 02411 shape->Nullify(); 02412 //delete shape; - Must not be deleted, causes random failure on OSX 02413 shape = NULL; 02414 } 02415 } 02416 } 02417 return CUBIT_SUCCESS; 02418 } 02419 02420 //=============================================================================== 02421 // Function : imprint_toposhapes 02422 // Member Type: PROTECTED 02423 // Description: imprint boolean operation on OCC-based bodies. 02424 // from_shape must be TopoDS_Face or above, tool_shape can be 02425 // TopoDS_Edge or above. 02426 // on_faces works only when tool_shape is an Edge, indicates that 02427 // those edges only imprint on the on_faces. 02428 // success: return 0 02429 // needs intersect-subtract-union boolean: return 1 02430 // fail: return 2 02431 // needs face intersect for periodic geometry: return 3 02432 // the cutting surface's topoDS_Face in returned in the 02433 // the last of on_faces list. 02434 // Author : Jane HU 02435 // Date : 03/08 02436 //=============================================================================== 02437 int OCCModifyEngine::imprint_toposhapes(TopoDS_Shape*& from_shape, 02438 TopoDS_Shape* tool_shape, 02439 DLIList<TopoDS_Face*>&on_faces)const 02440 { 02441 int count = 0; //number of imprinting 02442 02443 //indicate if there's more faces to be imprinted 02444 CubitBoolean more_face = CUBIT_TRUE; 02445 CubitBoolean face_created = CUBIT_FALSE; 02446 02447 //list of face on from_shape that has been imprinted 02448 DLIList<TopoDS_Face*> from_faces; 02449 while( more_face) 02450 { 02451 TopoDS_Face from_face,tool_face; 02452 TopoDS_Edge* common_edge = NULL; 02453 DLIList<TopoDS_Shape*> tool_faces_edges; 02454 TopTools_ListOfShape list_of_edges; 02455 BRepFeat_SplitShape splitor(*from_shape); 02456 CubitBoolean qualified = CUBIT_TRUE; 02457 if (tool_shape->ShapeType() == TopAbs_EDGE) 02458 { 02459 if(count == 1) 02460 break; 02461 02462 DLIList<TopoDS_Face*> faces; 02463 //need to delete TopoDS_Face* in faces 02464 common_edge = find_imprinting_edge(*from_shape, TopoDS::Edge(*tool_shape),faces); 02465 if (common_edge) 02466 { 02467 if (on_faces.size() > 0) 02468 qualified = CUBIT_FALSE; 02469 for(int j = 0; j < faces.size(); j++) 02470 { 02471 from_face = *faces.get(); 02472 for (int i = 0; i < on_faces.size(); i++) 02473 { 02474 if (from_face.IsSame(*(on_faces.get_and_step()))) 02475 { 02476 qualified = CUBIT_TRUE; 02477 break; 02478 } 02479 } 02480 faces.get()->Nullify(); 02481 delete faces.get(); 02482 faces.step(); 02483 } 02484 if (qualified && (from_faces.size() == 0 || (from_faces.size() && !from_face.IsSame(*from_faces.get()))) ) 02485 list_of_edges.Append(*common_edge); 02486 else 02487 from_face.Nullify(); 02488 common_edge->Nullify(); 02489 delete common_edge; 02490 common_edge = NULL; 02491 } 02492 } 02493 else 02494 { 02495 TopOpeBRep_ShapeIntersector intersector; 02496 intersector.InitIntersection(*from_shape, *tool_shape); 02497 02498 //find the intersecting edges and faces. 02499 int max_edge = 0; 02500 02501 for(; intersector.MoreIntersection(); ) 02502 { 02503 TopoDS_Shape face1; 02504 face1 = intersector.ChangeFacesIntersector().Face(1); 02505 CubitBoolean has_imprinted = CUBIT_FALSE; 02506 for (int j = 0; j < from_faces.size(); j++) 02507 { 02508 TopoDS_Face* topo_face = from_faces.get_and_step(); 02509 if(face1.IsSame(*topo_face)) 02510 { 02511 has_imprinted = CUBIT_TRUE; 02512 break; 02513 } 02514 } 02515 02516 if (has_imprinted == CUBIT_TRUE) 02517 { 02518 intersector.NextIntersection(); 02519 continue; 02520 } 02521 TopoDS_Shape edge_face; 02522 02523 edge_face = intersector.ChangeFacesIntersector().Face(2); 02524 BRepAlgoAPI_Section section(face1, edge_face); 02525 02526 //intersection edges between face1 and edge_face 02527 TopTools_ListOfShape temp_list_of_edges; 02528 #if OCC_VERSION_MINOR > 5 02529 TopoDS_Shape s_shape = section.Shape(); 02530 TopExp_Explorer Ex; 02531 for (Ex.Init(s_shape, TopAbs_EDGE, TopAbs_WIRE); Ex.More(); Ex.Next()) 02532 temp_list_of_edges.Append(TopoDS::Edge( Ex.Current())); 02533 #else 02534 temp_list_of_edges.Assign(section.SectionEdges()); 02535 #endif 02536 int num_edges = temp_list_of_edges.Extent(); 02537 02538 CubitBoolean is_same = face1.IsSame(from_face); 02539 CubitBoolean is_same_tool = CUBIT_FALSE; 02540 for (int j = 0; j < tool_faces_edges.size(); j++) 02541 { 02542 TopoDS_Shape* topo_face_edge = tool_faces_edges.get_and_step(); 02543 if(edge_face.IsSame(*topo_face_edge)) 02544 { 02545 is_same_tool = CUBIT_TRUE; 02546 break; 02547 } 02548 } 02549 if (max_edge < num_edges ) 02550 { 02551 list_of_edges.Assign(temp_list_of_edges); 02552 max_edge = num_edges ; 02553 from_face = TopoDS::Face(face1); 02554 TopoDS_Shape* topo_shape = new TopoDS_Shape(edge_face); 02555 DLIList<TopoDS_Shape*> shape_list; 02556 for(int iii = 0; iii < tool_faces_edges.size(); iii++) 02557 { 02558 int size = shape_list.size(); 02559 shape_list.append_unique(tool_faces_edges.get_and_step()); 02560 if (size < shape_list.size()) 02561 { 02562 shape_list.last(); 02563 shape_list.get()->Nullify(); 02564 delete shape_list.get(); 02565 } 02566 } 02567 tool_faces_edges.clean_out(); 02568 for(int i = 0 ; i < num_edges; i++) 02569 //later has to use it num_edges times 02570 tool_faces_edges.append(topo_shape); 02571 } 02572 else if(num_edges == max_edge && is_same && !is_same_tool) 02573 //multi tool faces cut the same face 02574 { 02575 TopTools_ListIteratorOfListOfShape Itor, temp_Itor; 02576 temp_Itor.Initialize(temp_list_of_edges); 02577 for(; temp_Itor.More(); temp_Itor.Next()) 02578 { 02579 TopoDS_Edge temp_edge = TopoDS::Edge(temp_Itor.Value()); 02580 Itor.Initialize(list_of_edges); 02581 CubitBoolean same_edge = CUBIT_FALSE; 02582 02583 GProp_GProps myProps1; 02584 BRepGProp::LinearProperties(temp_edge, myProps1); 02585 gp_Pnt center1 = myProps1.CentreOfMass(); 02586 for(; Itor.More(); Itor.Next()) 02587 { 02588 TopoDS_Edge edge = TopoDS::Edge(Itor.Value()); 02589 GProp_GProps myProps2; 02590 BRepGProp::LinearProperties(edge, myProps2); 02591 gp_Pnt center2 = myProps2.CentreOfMass(); 02592 if(center1.IsEqual(center2, TOL)) 02593 { 02594 same_edge = CUBIT_TRUE; 02595 break; 02596 } 02597 } 02598 if(!same_edge) 02599 { 02600 list_of_edges.Append(temp_edge); 02601 TopoDS_Shape* topo_shape = new TopoDS_Shape(edge_face); 02602 tool_faces_edges.append(topo_shape); 02603 } 02604 }//end 'for' 02605 }//end 'else if' 02606 intersector.NextIntersection(); 02607 } //end 'for' 02608 }//end 'else' 02609 if (from_face.IsNull()) 02610 { 02611 more_face = CUBIT_FALSE; 02612 DLIList<TopoDS_Shape*> shape_list; 02613 for(int iii = 0; iii < tool_faces_edges.size(); iii++) 02614 { 02615 int size = shape_list.size(); 02616 shape_list.append_unique(tool_faces_edges.get_and_step()); 02617 if (size < shape_list.size()) 02618 { 02619 shape_list.last(); 02620 shape_list.get()->Nullify(); 02621 delete shape_list.get(); 02622 } 02623 } 02624 tool_faces_edges.clean_out(); 02625 02626 for (int iii=0; iii < from_faces.size(); iii++) 02627 { 02628 TopoDS_Face* topo_face = from_faces.get_and_step(); 02629 topo_face->Nullify(); 02630 delete topo_face; 02631 topo_face = NULL; 02632 } 02633 continue; 02634 } 02635 02636 TopTools_ListIteratorOfListOfShape Itor; 02637 02638 //list_of_edges is the intersection edges on tool_faces_edges 02639 Itor.Initialize(list_of_edges); 02640 int total_edges = list_of_edges.Extent(); 02641 DLIList<Curve*> curve_list; 02642 DLIList<OCCCurve*> occ_curves; 02643 CubitBoolean topo_changed = CUBIT_FALSE; 02644 tool_faces_edges.reset(); 02645 02646 //check to see if the intersection edge is: 02647 //1. on from_face: if not, skip it 02648 //2. overlap with from_edges : if not, add the edge for splitting face 02649 //3. if overlap, is it the same edge:if not add it for splitting edge 02650 // if yes, skip it too 02651 02652 Surface* face = NULL; 02653 if (OCCQueryEngine::instance()->OCCMap->IsBound(from_face)) 02654 { 02655 int i = OCCQueryEngine::instance()->OCCMap->Find(from_face); 02656 face = (OCCSurface*)(OCCQueryEngine::instance()->OccToCGM->find(i))->second; 02657 } 02658 if (face == NULL) 02659 { 02660 face_created = CUBIT_TRUE; 02661 face = OCCQueryEngine::instance()->populate_topology_bridge(from_face); 02662 } 02663 OCCSurface* occ_face = CAST_TO(face, OCCSurface); 02664 02665 GeometryType type = occ_face->geometry_type(); 02666 CubitBoolean periodic = occ_face->is_periodic(); 02667 02668 DLIList<Curve*> common_curves; 02669 for(; Itor.More(); Itor.Next()) 02670 { 02671 TopoDS_Edge edge = TopoDS::Edge(Itor.Value()); 02672 02673 //copy the edge for imprinting. 02674 BRepBuilderAPI_Copy api_copy(edge); 02675 TopoDS_Shape newShape = api_copy.ModifiedShape(edge); 02676 edge = TopoDS::Edge(newShape); 02677 Curve* curve = NULL; 02678 if(!OCCQueryEngine::instance()->OCCMap->IsBound(edge)) 02679 { 02680 curve = OCCQueryEngine::instance()->populate_topology_bridge(edge, true); 02681 DLIList<OCCPoint*> points; 02682 OCCCurve* occ_c = CAST_TO(curve, OCCCurve); 02683 occ_c->get_points(points); 02684 for(int i = 0 ; i < points.size(); i++) 02685 points.get_and_step()->remove_curve(occ_c); 02686 } 02687 else 02688 curve = OCCQueryEngine::instance()->populate_topology_bridge(edge); 02689 if(curve) 02690 common_curves.append(curve); 02691 } 02692 DLIList<DLIList<TopoDS_Edge*>*> temp_edge_lists; 02693 if (common_curves.size() >= 1) 02694 sort_curves(common_curves, temp_edge_lists); 02695 02696 if ( common_curves.size() >= 2 && 02697 (type == CONE_SURFACE_TYPE || type == SPHERE_SURFACE_TYPE || 02698 type == TORUS_SURFACE_TYPE ||type == UNDEFINED_SURFACE_TYPE || 02699 type == SPLINE_SURFACE_TYPE)) 02700 { 02701 //if the two shapes has common volume, do boolean operations 02702 BRepAlgoAPI_Common intersector(*from_shape, *tool_shape); 02703 TopTools_ListOfShape shapes; 02704 shapes.Assign(intersector.Modified(*tool_shape)); 02705 02706 TopoDS_Shape common_shape; 02707 if (shapes.IsEmpty()) 02708 common_shape = intersector.Shape(); 02709 else 02710 common_shape = shapes.First(); 02711 02712 if(!common_shape.IsNull()) 02713 { 02714 TopTools_IndexedMapOfShape M; 02715 TopExp::MapShapes(common_shape, TopAbs_SOLID, M); 02716 if(M.Extent() > 0) 02717 { 02718 GProp_GProps myProps; 02719 BRepGProp::VolumeProperties(common_shape, myProps); 02720 double after_mass = myProps.Mass(); 02721 BRepGProp::VolumeProperties(*from_shape, myProps); 02722 double orig_mass = myProps.Mass(); 02723 if(fabs(-after_mass + orig_mass) > TOL && after_mass > TOL) 02724 return 1; 02725 } 02726 //have to use boolean operation, see 02727 //http://www.opencascade.org/org/forum/thread_20672/ for more info 02728 } 02729 } 02730 02731 list_of_edges.Clear(); 02732 if (common_curves.size() >= 1) 02733 { 02734 DLIList<TopoDS_Edge*>* edge_list; 02735 int size = temp_edge_lists.size(); 02736 for(int i = 0; i < size; i++) 02737 { 02738 edge_list = temp_edge_lists.get_and_step(); 02739 //make sure the copied edges are sharing vertices. 02740 BRepBuilderAPI_MakeWire myWire; 02741 edge_list->reset(); 02742 for(int j = 0; j < edge_list->size(); j++) 02743 { 02744 TopoDS_Edge e = *(edge_list->get_and_step()); 02745 //Don't include zero length edge. 02746 GProp_GProps myProps; 02747 BRepGProp::LinearProperties(e, myProps); 02748 double d = myProps.Mass(); 02749 if(d > TOL) 02750 myWire.Add(e); 02751 } 02752 TopoDS_Wire wire = myWire.Wire(); 02753 BRepTools_WireExplorer Ex(wire); 02754 for(; Ex.More(); Ex.Next()) 02755 list_of_edges.Append(Ex.Current()); 02756 edge_list->clean_out(); 02757 delete edge_list; 02758 } 02759 } 02760 for(Itor.Initialize(list_of_edges); Itor.More(); Itor.Next()) 02761 { 02762 TopoDS_Edge edge = TopoDS::Edge(Itor.Value()); 02763 CubitBoolean added = CUBIT_FALSE; 02764 //check to see if the intersection edge is on from_face 02765 TopExp_Explorer Ex; 02766 CubitBoolean skipped = CUBIT_FALSE; 02767 GProp_GProps myProps1; 02768 BRepGProp::LinearProperties(edge, myProps1); 02769 double d1 = myProps1.Mass(); 02770 Curve* curve = NULL; 02771 //edge should all be bounded, it comes from common_curves 02772 if (OCCQueryEngine::instance()->OCCMap->IsBound(edge)) 02773 { 02774 int i = OCCQueryEngine::instance()->OCCMap->Find(edge); 02775 curve = (Curve*) 02776 (OCCQueryEngine::instance()->OccToCGM->find(i))->second; 02777 } 02778 else 02779 { 02780 curve = OCCQueryEngine::instance()->populate_topology_bridge(edge, true); 02781 DLIList<OCCPoint*> points; 02782 OCCCurve* occ_c = CAST_TO(curve, OCCCurve); 02783 occ_c->get_points(points); 02784 for(int i = 0 ; i < points.size(); i++) 02785 points.get_and_step()->remove_curve(occ_c); 02786 } 02787 gp_Pnt pt = myProps1.CentreOfMass(); 02788 CubitVector p = curve->center_point(); 02789 02790 CubitVector point_on_surf; 02791 occ_face->closest_point_trimmed(p, point_on_surf); 02792 02793 if(p.distance_between(point_on_surf) > TOL) //edge not on from_face 02794 { 02795 skipped = CUBIT_TRUE; 02796 total_edges--; 02797 } 02798 02799 else 02800 { 02801 for (Ex.Init(from_face, TopAbs_EDGE); Ex.More(); Ex.Next()) 02802 { 02803 //check if the edge is on from_face edges, add such edge on existing 02804 //edge to split it. 02805 TopoDS_Edge from_edge = TopoDS::Edge(Ex.Current()); 02806 02807 GProp_GProps myProps2; 02808 BRepGProp::LinearProperties(from_edge, myProps2); 02809 double d2 = myProps2.Mass(); 02810 gp_Pnt pt2 = myProps2.CentreOfMass(); 02811 CubitBoolean found_ = CUBIT_FALSE; 02812 Curve* from_curve; 02813 if (OCCQueryEngine::instance()->OCCMap->IsBound(from_edge)) 02814 { 02815 int i = OCCQueryEngine::instance()->OCCMap->Find(from_edge); 02816 from_curve = (OCCCurve*) 02817 (OCCQueryEngine::instance()->OccToCGM->find(i))->second; 02818 found_ = CUBIT_TRUE; 02819 } 02820 else 02821 from_curve = OCCQueryEngine::instance()->populate_topology_bridge(from_edge, true); 02822 if(!from_curve) 02823 continue; 02824 02825 OCCCurve* occ_curve = CAST_TO(from_curve, OCCCurve); 02826 02827 if(pt.IsEqual(pt2, TOL) && fabs(d2-d1)< TOL) //overlap 02828 { 02829 skipped = CUBIT_TRUE; 02830 total_edges--; 02831 break; 02832 } 02833 02834 CubitPointContainment pc = CUBIT_PNT_OFF; 02835 pc = occ_curve->point_containment(p); 02836 if((d2 - d1) > TOL && pc == CUBIT_PNT_ON) 02837 { 02838 added = CUBIT_TRUE; 02839 splitor.Add(edge, from_edge); 02840 total_edges--; 02841 break; 02842 } 02843 02844 if(!found_ && from_curve) 02845 OCCQueryEngine::instance()-> 02846 delete_solid_model_entities(from_curve); 02847 } 02848 if(list_of_edges.Extent() == 1 && !skipped) 02849 { 02850 added = CUBIT_TRUE; 02851 curve_list.append(curve); 02852 } 02853 } 02854 if(added) 02855 { 02856 topo_changed = CUBIT_TRUE; 02857 continue; 02858 } 02859 if (!skipped) 02860 { 02861 //check if edge's inside from_face by checking bounding boxes 02862 BRepAdaptor_Curve acurve(edge); 02863 BRepAdaptor_Surface asurface( from_face); 02864 Bnd_Box aBox_edge, aBox_face; 02865 BndLib_Add3dCurve::Add(acurve, Precision::Approximation(), aBox_edge); 02866 BndLib_AddSurface::Add(asurface, Precision::Approximation(), aBox_face); 02867 double min[3], max[3]; 02868 aBox_edge.Get( min[0], min[1], min[2], max[0], max[1], max[2]); 02869 CubitBox aBox_e(min, max); 02870 aBox_face.Get( min[0], min[1], min[2], max[0], max[1], max[2]); 02871 CubitBox aBox_f(min, max); 02872 //hexlat3 has tolerance issue where aBox_e.x_min is within 02873 //tolerance and greater than aBox_f.x_min, causing no edge 02874 //imprint of the faces. change to add consideration of tolerance 02875 // lose the bounding box critiral a little more. 02876 int num_satisfied = 0; 02877 02878 if (aBox_f.min_x() >= 0 && aBox_e.min_x() >= aBox_f.min_x() *0.9) 02879 num_satisfied ++; 02880 if(aBox_f.min_x() < 0 && aBox_e.min_x() >= aBox_f.min_x() *1.1) 02881 num_satisfied ++; 02882 02883 if (aBox_f.min_y() >= 0 && aBox_e.min_y() >= aBox_f.min_y() *0.9) 02884 num_satisfied ++; 02885 if(aBox_f.min_y() < 0 && aBox_e.min_y() >= aBox_f.min_y() *1.1) 02886 num_satisfied ++; 02887 02888 if(aBox_f.min_z() >= 0 && aBox_e.min_z() >= aBox_f.min_z() *0.9) 02889 num_satisfied ++; 02890 if (aBox_f.min_z() < 0 && aBox_e.min_z() >= aBox_f.min_z() *1.1) 02891 num_satisfied ++; 02892 02893 if (aBox_f.max_x() > 0 && aBox_e.max_x() <= aBox_f.max_x() *1.1) 02894 num_satisfied ++; 02895 if(aBox_f.max_x() <= 0 && aBox_e.max_x() <= aBox_f.max_x() *0.9) 02896 num_satisfied ++; 02897 if( aBox_f.max_y() > 0 && aBox_e.max_y() <= aBox_f.max_y() *1.1) 02898 num_satisfied ++; 02899 if( aBox_f.max_y() <= 0 && aBox_e.max_y() <= aBox_f.max_y() *0.9) 02900 num_satisfied ++; 02901 if( aBox_f.max_z() >= 0 && aBox_e.max_z() <= aBox_f.max_z() *1.1) 02902 num_satisfied ++; 02903 if( aBox_f.max_z() < 0 && aBox_e.max_z() <= aBox_f.max_z() *0.9) 02904 num_satisfied ++; 02905 02906 if(num_satisfied == 6) 02907 { 02908 curve_list.append_unique(curve); 02909 } 02910 else 02911 { 02912 curve_list.remove(curve); 02913 OCCQueryEngine::instance()->delete_solid_model_entities( curve ); 02914 total_edges--; 02915 } 02916 } 02917 } 02918 02919 if(face_created) 02920 { 02921 OCCQueryEngine::instance()->delete_solid_model_entities(occ_face); 02922 face_created = CUBIT_FALSE; 02923 } 02924 DLIList<DLIList<TopoDS_Edge*>*> edge_lists; 02925 if ( total_edges >= 1) 02926 { 02927 CubitStatus stat = CUBIT_SUCCESS; 02928 if(curve_list.size() > 0) 02929 stat = sort_curves(curve_list, edge_lists); 02930 else 02931 { 02932 TopoDS_Face* topo_face = new TopoDS_Face(from_face); 02933 from_faces.append(topo_face); 02934 continue; 02935 } 02936 DLIList<TopoDS_Edge*>* edge_list; 02937 int size = edge_lists.size(); 02938 02939 //if size > 1 , outer wire first. 02940 DLIList<CubitBox*> bs; 02941 edge_lists.reset(); 02942 CubitBox box; 02943 for(int i = 0; i < size && size > 1; i++) 02944 { 02945 edge_list = edge_lists.get_and_step(); 02946 for(int j = 0; j < edge_list->size(); j++) 02947 { 02948 TopoDS_Edge e = *(edge_list->get_and_step()); 02949 CubitBoolean bound = CUBIT_FALSE; 02950 Curve* curve = NULL; 02951 if(OCCQueryEngine::instance()->OCCMap->IsBound(e)) 02952 { 02953 int k = OCCQueryEngine::instance()->OCCMap->Find(e); 02954 bound = CUBIT_TRUE; 02955 curve = (Curve*)(OCCQueryEngine::instance()->OccToCGM->find(k))->second; 02956 } 02957 else 02958 curve = OCCQueryEngine::instance()-> 02959 populate_topology_bridge(e, true); 02960 if(j == 0) 02961 box = curve->bounding_box(); 02962 else 02963 box |= curve->bounding_box(); 02964 if(!bound) 02965 OCCQueryEngine::instance()->delete_solid_model_entities(curve); 02966 } 02967 CubitBox* pbox = new CubitBox(box); 02968 bs.append(pbox); 02969 } 02970 bs.append((CubitBox*) NULL); 02971 02972 for(int i = 0; i < size-1; i++) 02973 { 02974 for(int j = i + 1; j < size; j ++) 02975 { 02976 edge_lists.reset(); 02977 if(*bs[j] <= *bs[i]) 02978 { 02979 edge_lists.step(j); 02980 edge_lists.get()->clean_out(); 02981 delete edge_lists.get(); 02982 edge_lists.change_to((DLIList<TopoDS_Edge*>*)NULL); 02983 continue; 02984 } 02985 if(*bs[i] <= *bs[j]) 02986 { 02987 edge_lists.step(i); 02988 edge_lists.get()->clean_out(); 02989 delete edge_lists.get(); 02990 edge_lists.change_to((DLIList<TopoDS_Edge*>*)NULL); 02991 break; 02992 } 02993 } 02994 } 02995 for(int i = 0; i < size && size > 1; i++) 02996 delete bs.pop(); 02997 02998 edge_lists.remove_all_with_value((DLIList<TopoDS_Edge*>*)NULL); 02999 03000 size = edge_lists.size(); 03001 for (int iii = 0; iii < size; iii++) 03002 { 03003 edge_list = edge_lists.pop(); 03004 03005 //check if the edges make a split of the surface, error out if it's 03006 //just a scar on the surface 03007 int count_intersection = 0; 03008 if (stat == CUBIT_FAILURE) //Open wire 03009 { 03010 count_intersection = check_intersection(edge_list, from_face); 03011 03012 if (count_intersection == 1 ) 03013 { 03014 PRINT_WARNING("Cant make a scar on existing face without splitting it. \n"); 03015 edge_list->clean_out(); 03016 delete edge_list; 03017 } 03018 } 03019 if (stat || count_intersection == 2) 03020 { 03021 BRepBuilderAPI_MakeWire myWire; 03022 edge_list->reset(); 03023 DLIList<Curve*> wire_curves; 03024 for(int i = 0; i < edge_list->size(); i++) 03025 { 03026 TopoDS_Edge e = *(edge_list->get_and_step()); 03027 //remove curve from its vertice's curve list 03028 if(OCCQueryEngine::instance()->OCCMap->IsBound(e)) 03029 { 03030 int j = OCCQueryEngine::instance()->OCCMap->Find(e); 03031 Curve* curve = (Curve*)(OCCQueryEngine::instance()->OccToCGM->find(j))->second; 03032 OCCCurve* curve_to_remove = (OCCCurve*) curve; 03033 wire_curves.append(curve); 03034 DLIList<OCCPoint*> points; 03035 curve_to_remove->get_points(points); 03036 for (int k = 0; k < points.size(); k++) 03037 points.get_and_step()->remove_curve(curve_to_remove); 03038 } 03039 else if(periodic && count_intersection != 2) 03040 { 03041 Curve* curve = OCCQueryEngine::instance()-> 03042 populate_topology_bridge(e,true); 03043 wire_curves.append(curve); 03044 } 03045 myWire.Add(e); 03046 } 03047 edge_list->clean_out(); 03048 delete edge_list; 03049 if(!periodic || count_intersection == 2 || 03050 type == PLANE_SURFACE_TYPE) 03051 { 03052 splitor.Add(myWire.Wire(),from_face); 03053 topo_changed = CUBIT_TRUE; 03054 03055 } 03056 else 03057 { 03058 //use the myWire to create a surface and webcut the 03059 //periodic body. 03060 Surface *wire_surf = make_Surface(BEST_FIT_SURFACE_TYPE, 03061 wire_curves); 03062 if(wire_surf == NULL) 03063 wire_surf = make_Surface(PLANE_SURFACE_TYPE, wire_curves); 03064 if(wire_surf) 03065 { 03066 OCCSurface* occ_wire_s = CAST_TO(wire_surf, OCCSurface); 03067 TopoDS_Face *topo_face = occ_wire_s->get_TopoDS_Face(); 03068 on_faces.append(topo_face); 03069 return 3; 03070 } 03071 } 03072 } 03073 } 03074 } 03075 if(topo_changed) 03076 { 03077 splitor.Build(); 03078 topo_changed = CUBIT_FALSE; 03079 if(splitor.IsDone()) 03080 { 03081 //take care of on_faces list first:after operation, the on_faces 03082 // will have at least one face changed, update the pointer. 03083 int size = on_faces.size(); 03084 if (size > 0) 03085 { 03086 for(int k = 0; k < size; k++) 03087 { 03088 TopoDS_Face* compare_face = on_faces.get(); 03089 TopTools_ListOfShape shapes; 03090 shapes.Assign(splitor.Modified(*compare_face)); 03091 if(shapes.Extent() > 0 && 03092 !compare_face->IsSame(shapes.First())) 03093 { 03094 on_faces.change_to(NULL); 03095 while(shapes.Extent() > 0) 03096 { 03097 TopoDS_Face* face = 03098 new TopoDS_Face(TopoDS::Face(shapes.First())); 03099 shapes.RemoveFirst(); 03100 on_faces.append(face); 03101 } 03102 } 03103 on_faces.step(); 03104 } 03105 on_faces.remove_all_with_value(NULL); 03106 } 03107 03108 TopoDS_Shape new_from_shape = splitor.Shape(); 03109 if(from_shape->ShapeType() == TopAbs_COMPOUND) 03110 { 03111 TopoDS_Compound old_csolid = TopoDS::Compound(*from_shape); 03112 OCCBody::update_OCC_entity(old_csolid, new_from_shape, &splitor); 03113 if(!old_csolid.IsEqual(new_from_shape)) 03114 { 03115 from_shape->Nullify(); 03116 *from_shape = new_from_shape; 03117 } 03118 } 03119 03120 else if(from_shape->ShapeType() == TopAbs_SOLID) 03121 { 03122 TopoDS_Solid old_solid = TopoDS::Solid(*from_shape); 03123 OCCLump::update_OCC_entity(old_solid, new_from_shape, &splitor); 03124 if(!old_solid.IsEqual(new_from_shape)) 03125 { 03126 from_shape->Nullify(); 03127 *from_shape = new_from_shape; 03128 } 03129 } 03130 else if(from_shape->ShapeType() == TopAbs_SHELL) 03131 { 03132 TopoDS_Shell old_shell = TopoDS::Shell(*from_shape); 03133 OCCShell::update_OCC_entity(old_shell,new_from_shape, &splitor); 03134 if(!old_shell.IsEqual(new_from_shape)) 03135 { 03136 from_shape->Nullify(); 03137 *from_shape = new_from_shape; 03138 } 03139 } 03140 else if(from_shape->ShapeType() == TopAbs_FACE) 03141 { 03142 TopoDS_Face old_face = TopoDS::Face(*from_shape); 03143 OCCSurface::update_OCC_entity(old_face,new_from_shape, &splitor); 03144 if(!old_face.IsEqual(new_from_shape)) 03145 { 03146 from_shape->Nullify(); 03147 *from_shape = new_from_shape; 03148 } 03149 } 03150 03151 TopTools_ListOfShape shapes; 03152 for(int i = 0; i < from_faces.size(); i++) 03153 { 03154 TopoDS_Face* topo_face = from_faces.get(); 03155 shapes.Assign(splitor.Modified(*topo_face)); 03156 topo_face = new TopoDS_Face(TopoDS::Face(shapes.First())); 03157 from_faces.get()->Nullify(); 03158 delete from_faces.get(); 03159 from_faces.change_to(topo_face); 03160 from_faces.step(); 03161 } 03162 count++; 03163 } 03164 } 03165 else 03166 { 03167 TopoDS_Face* topo_face = new TopoDS_Face(from_face); 03168 from_faces.append(topo_face); 03169 } 03170 } 03171 03172 TopExp_Explorer Ex; 03173 int num_face = 0; 03174 for (Ex.Init(*from_shape, TopAbs_FACE); Ex.More(); Ex.Next()) 03175 { 03176 TopoDS_Face face = TopoDS::Face(Ex.Current()); 03177 num_face++; 03178 } 03179 03180 #ifdef DEBUG 03181 PRINT_INFO("Total %d cuts performed, with from_shape having %d faces.\n", count, num_face); 03182 #endif 03183 03184 if (count > 0) 03185 return 0; 03186 return 2; 03187 } 03188 03189 //=============================================================================== 03190 // Function : find_imprinting_edge 03191 // Member Type: PROTECTED 03192 // Description: imprint boolean operation on OCC-based bodies. 03193 // from_shape must be TopoDS_Face or above, tool_shape must be 03194 // TopoDS_Edge. 03195 // Author : Jane HU 03196 // Date : 05/08 03197 //=============================================================================== 03198 TopoDS_Edge* OCCModifyEngine::find_imprinting_edge(TopoDS_Shape& from_shape, 03199 TopoDS_Edge& tool_shape, 03200 DLIList<TopoDS_Face*>& from_faces)const 03201 { 03202 TopoDS_Edge* edge = NULL; 03203 //list of face on from_shape that has been imprinted 03204 from_faces.clean_out(); 03205 BRepAdaptor_Curve acurve(tool_shape); 03206 Bnd_Box aBox_edge, aBox_face; 03207 BndLib_Add3dCurve::Add(acurve, Precision::Approximation(), aBox_edge); 03208 03209 TopExp_Explorer Ex; 03210 for (Ex.Init(from_shape, TopAbs_FACE); Ex.More(); Ex.Next()) 03211 { 03212 TopoDS_Face face = TopoDS::Face(Ex.Current()); 03213 BRepAdaptor_Surface asurface( face); 03214 aBox_face.SetVoid(); 03215 BndLib_AddSurface::Add(asurface, Precision::Approximation(), aBox_face); 03216 if (aBox_face.IsOut(aBox_edge)) 03217 continue; 03218 03219 BRepAlgoAPI_Common intersector(face, tool_shape); 03220 TopTools_ListOfShape shapes; 03221 shapes.Assign(intersector.Generated(tool_shape)); 03222 if(shapes.IsEmpty()) 03223 shapes.Assign(intersector.Modified(tool_shape)); 03224 if (shapes.IsEmpty()) 03225 continue; 03226 if ( shapes.Extent() > 1) 03227 { 03228 PRINT_ERROR("Edge has multiple intersection with the shape, make it simpler. \n"); 03229 continue; 03230 } 03231 if (shapes.First().ShapeType() != TopAbs_EDGE && 03232 shapes.First().ShapeType() != TopAbs_COMPOUND) 03233 continue; 03234 03235 TopoDS_Shape result = shapes.First(); 03236 TopoDS_Edge common_edge; 03237 if(edge == NULL && result.ShapeType() == TopAbs_EDGE) 03238 common_edge = TopoDS::Edge(result); 03239 03240 else if(edge == NULL && 03241 result.ShapeType() == TopAbs_COMPOUND) 03242 { 03243 TopExp_Explorer Ex(result, TopAbs_EDGE); 03244 if(Ex.More()) 03245 common_edge = TopoDS::Edge(Ex.Current()); 03246 } 03247 if (common_edge.IsNull()) 03248 continue; 03249 BRepBuilderAPI_Copy api_copy(common_edge); 03250 TopoDS_Shape newShape = api_copy.ModifiedShape(common_edge); 03251 edge = new TopoDS_Edge(TopoDS::Edge(newShape)); 03252 03253 from_faces.append(new TopoDS_Face(face)); 03254 } 03255 return edge; 03256 } 03257 03258 int OCCModifyEngine::check_intersection(DLIList<TopoDS_Edge*>*& edge_list, 03259 TopoDS_Face from_face)const 03260 { 03261 int count_intersection = 0; 03262 03263 gp_Pnt newP[2] , p_test ; 03264 for(int kk = 0; kk < edge_list->size(); kk++) 03265 { 03266 TopoDS_Edge* edge = edge_list->get_and_step(); 03267 BRepAdaptor_Curve acurve(*edge); 03268 double lower_bound = acurve.FirstParameter(); 03269 double upper_bound = acurve.LastParameter(); 03270 TopExp_Explorer Ex; 03271 for (Ex.Init(from_face, TopAbs_EDGE); Ex.More(); Ex.Next()) 03272 { 03273 TopoDS_Edge from_edge = TopoDS::Edge(Ex.Current()); 03274 BRepAdaptor_Curve acurve2(from_edge); 03275 double lower_bound2 = acurve2.FirstParameter(); 03276 double upper_bound2 = acurve2.LastParameter(); 03277 BRepExtrema_DistShapeShape distShapeShape(*edge, from_edge); 03278 03279 if (distShapeShape.IsDone() && distShapeShape.Value() < TOL) 03280 { 03281 //double check that the point is on the edges. 03282 double newVal; 03283 for(int j =1; j <= distShapeShape.NbSolution(); j++) 03284 { 03285 if(count_intersection == 2) 03286 break; 03287 03288 p_test = distShapeShape.PointOnShape1(j); 03289 Extrema_ExtPC ext(p_test, acurve, Precision::Approximation()); 03290 // At this time, there must be a intersection point at least. 03291 if (ext.IsDone() && (ext.NbExt() > 0)) { 03292 for ( int i = 1 ; i <= ext.NbExt() ; i++ ) { 03293 newVal = ext.Point(i).Parameter(); 03294 if ((newVal-lower_bound) >= -TOL && 03295 (upper_bound - newVal) >= -TOL) 03296 { 03297 Extrema_ExtPC ext(p_test, acurve2, Precision::Approximation()); 03298 if (ext.IsDone() && (ext.NbExt() > 0)) { 03299 for ( int k = 1 ; k <= ext.NbExt() ; k++ ) { 03300 newVal = ext.Point(i).Parameter(); 03301 if ((newVal-lower_bound2) >= -TOL && 03302 (upper_bound2 - newVal) >= -TOL) 03303 { 03304 newP[count_intersection] = p_test; 03305 count_intersection ++; 03306 break; 03307 } 03308 } 03309 } 03310 } 03311 } 03312 } 03313 } 03314 } 03315 03316 if (count_intersection == 2) 03317 { 03318 //make sure the two intersect point are not the same one 03319 if (newP[0].IsEqual(newP[1], TOL)) 03320 count_intersection--; 03321 } 03322 if (count_intersection == 2) 03323 break; 03324 } //for loop 03325 } 03326 return count_intersection; 03327 } 03328 //=============================================================================== 03329 // Function : imprint 03330 // Member Type: PUBLIC 03331 // Description: imprint boolean operation on OCC-based bodies 03332 // Author : Jane Hu 03333 // Date : 04/08 03334 //=============================================================================== 03335 CubitStatus OCCModifyEngine::imprint(BodySM* BodyPtr1, BodySM* BodyPtr2, 03336 BodySM*& newBody1, BodySM*& newBody2, 03337 bool keep_old) const 03338 { 03339 newBody1 = NULL; 03340 newBody2 = NULL; 03341 DLIList<TopoDS_Shape*> shape_list; 03342 DLIList<CubitBoolean> is_volume; 03343 03344 DLIList<BodySM*> bodysm_list; 03345 bodysm_list.append(BodyPtr1); 03346 bodysm_list.append(BodyPtr2); 03347 03348 CubitStatus stat = get_shape_list(bodysm_list,shape_list,is_volume,keep_old); 03349 03350 if(!stat) 03351 return stat; 03352 03353 TopoDS_Shape* shape1 = shape_list.get(); 03354 TopoDS_Shape* shape2 = shape_list.step_and_get(); 03355 DLIList<TopologyBridge*> tbs; 03356 DLIList<TopoDS_Face*> face_list; 03357 int result = imprint_toposhapes(shape1, shape2, face_list); 03358 if(result == 0) 03359 { 03360 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*shape1); 03361 newBody1 = CAST_TO(tbs.get(),BodySM); 03362 } 03363 03364 else if(result == 1) 03365 { 03366 //for cylinder overlapping cases, doing boolean operation is necessary for 03367 //now. 10/25/11 03368 BodySM* tool_copy = copy_body(BodyPtr2); 03369 /* 03370 DLIList<BodySM*> tools; 03371 tools.append(tool_copy); 03372 DLIList<BodySM*> from_bodies ; 03373 BodySM* from_copy = copy_body(BodyPtr1); 03374 from_bodies.append(from_copy); 03375 DLIList<BodySM*> new_bodies; 03376 stat = subtract(tools, from_bodies, new_bodies, false, false); 03377 if (stat) 03378 { 03379 tool_copy = copy_body(BodyPtr2); 03380 from_bodies.clean_out(); 03381 from_bodies.append(BodyPtr1); 03382 intersect(tool_copy, from_bodies, new_bodies, false); 03383 if(new_bodies.size() > 1) 03384 { 03385 DLIList<BodySM*> final_bodies; 03386 unite(new_bodies, final_bodies, false); 03387 newBody1 = final_bodies.get(); 03388 } 03389 else 03390 newBody1 = new_bodies.get(); 03391 } 03392 */ 03393 stat = result_1_imprint(BodyPtr1, tool_copy, newBody1); 03394 if(stat == CUBIT_FAILURE) 03395 result = 2; 03396 } 03397 else if(result == 3) 03398 { 03399 TopoDS_Face* face = face_list.pop(); 03400 int j = OCCQueryEngine::instance()->OCCMap->Find(*face); 03401 OCCSurface* cut_face = (OCCSurface*)(OCCQueryEngine::instance()->OccToCGM->find(j))->second; 03402 OCCBody* tool_body = cut_face->my_body(); 03403 stat = result_3_imprint(BodyPtr1,tool_body, newBody1); 03404 if(stat == CUBIT_FAILURE) 03405 result = 2; 03406 } 03407 03408 if(result && keep_old) 03409 { 03410 delete shape1; 03411 shape1 = NULL; 03412 PRINT_INFO("There's no imprint on the first body.\n"); 03413 newBody1 = BodyPtr1; 03414 } 03415 03416 tbs.clean_out(); 03417 result = imprint_toposhapes(shape2, shape1, face_list); 03418 if(result == 0) 03419 { 03420 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*shape2); 03421 newBody2 = CAST_TO(tbs.get(),BodySM); 03422 } 03423 03424 else if(result == 1) 03425 { 03426 //for cylinder overlapping cases, doing boolean operation is necessary for 03427 //now. 10/25/11 03428 BodySM* tool_copy = copy_body(BodyPtr1); 03429 /* 03430 DLIList<BodySM*> tools; 03431 tools.append(tool_copy); 03432 DLIList<BodySM*> from_bodies ; 03433 BodySM* from_copy = copy_body(BodyPtr2); 03434 from_bodies.append(from_copy); 03435 DLIList<BodySM*> new_bodies; 03436 stat = subtract(tools, from_bodies, new_bodies, false, false); 03437 if (stat) 03438 { 03439 tool_copy = copy_body(BodyPtr1); 03440 from_bodies.clean_out(); 03441 from_bodies.append(BodyPtr2); 03442 intersect(tool_copy, from_bodies, new_bodies, false); 03443 if(new_bodies.size() > 1) 03444 { 03445 DLIList<BodySM*> final_bodies; 03446 unite(new_bodies, final_bodies, false); 03447 newBody2 = final_bodies.get(); 03448 } 03449 else 03450 newBody2 = new_bodies.get(); 03451 } 03452 */ 03453 stat = result_1_imprint(BodyPtr2, tool_copy, newBody2); 03454 if(stat == CUBIT_FAILURE) 03455 result = 2; 03456 } 03457 03458 else if(result == 3) 03459 { 03460 TopoDS_Face* face = face_list.pop(); 03461 int j = OCCQueryEngine::instance()->OCCMap->Find(*face); 03462 OCCSurface* cut_face = (OCCSurface*)(OCCQueryEngine::instance()->OccToCGM->find(j))->second; 03463 OCCBody* tool_body = cut_face->my_body(); 03464 stat = result_3_imprint(BodyPtr2,tool_body, newBody2); 03465 if(stat == CUBIT_FAILURE) 03466 result = 2; 03467 } 03468 03469 if(result && keep_old) 03470 { 03471 delete shape2; 03472 shape2 = NULL; 03473 PRINT_INFO("There's no imprint on the second body.\n"); 03474 newBody2 = BodyPtr2; 03475 } 03476 return CUBIT_SUCCESS; 03477 } 03478 03479 //=============================================================================== 03480 // Function : get_shape_list 03481 // Member Type: PRIVATE 03482 // Description: get the TopoDS_Shape list for imprinting use. 03483 // Author : Jane Hu 03484 // Date : 05/08 03485 //=============================================================================== 03486 CubitStatus OCCModifyEngine::get_shape_list(DLIList<BodySM*>& BodySM_list, 03487 DLIList<TopoDS_Shape*>& shape_list, 03488 DLIList<CubitBoolean>& is_volume, 03489 bool keep_old, 03490 DLIList<CubitBox*>* b_boxes) const 03491 { 03492 OCCBody* occ_body = NULL; 03493 shape_list.clean_out(); 03494 is_volume.clean_out(); 03495 CubitStatus stat = CUBIT_SUCCESS; 03496 for(int i = 0; i <BodySM_list.size(); i++) 03497 { 03498 occ_body = CAST_TO(BodySM_list.get_and_step(), OCCBody); 03499 if (!occ_body) 03500 continue; 03501 03502 if(b_boxes) 03503 { 03504 CubitBox *tool_box = new CubitBox(occ_body->get_bounding_box()); 03505 b_boxes->append(tool_box); 03506 } 03507 03508 TopoDS_Compound* shape = occ_body->get_TopoDS_Shape(); 03509 if( shape && !shape->IsNull()) 03510 { 03511 if(keep_old) 03512 { 03513 BRepBuilderAPI_Copy api_copy(*shape); 03514 TopoDS_Shape newShape = api_copy.ModifiedShape(*shape); 03515 TopoDS_Shape* Shape1 = new TopoDS_Shape(newShape); 03516 shape_list.append(Shape1); 03517 } 03518 else 03519 shape_list.append_unique(shape); 03520 TopExp_Explorer Ex(*shape, TopAbs_SOLID); 03521 if(Ex.More()) 03522 is_volume.append( CUBIT_TRUE); 03523 else 03524 is_volume.append( CUBIT_FALSE); 03525 continue; 03526 } 03527 03528 DLIList<OCCSurface*> surfaces; 03529 DLIList<OCCShell*> shells; 03530 DLIList<OCCCurve*> curves; 03531 03532 surfaces = occ_body->my_sheet_surfaces(); 03533 shells = occ_body->shells(); 03534 if(surfaces.size() + shells.size() > 1) 03535 { 03536 PRINT_ERROR("Can't do boolean operation on multiple-volume body.\n"); 03537 stat = CUBIT_FAILURE; 03538 break; 03539 } 03540 is_volume.append( CUBIT_TRUE); 03541 03542 if(surfaces.size() == 1) 03543 { 03544 TopoDS_Face* topo_face = surfaces.get()->get_TopoDS_Face(); 03545 if(!topo_face) 03546 { 03547 stat = CUBIT_FAILURE; 03548 break; 03549 } 03550 if(keep_old) 03551 { 03552 BRepBuilderAPI_Copy api_copy(*topo_face); 03553 TopoDS_Shape newShape = api_copy.ModifiedShape(*topo_face); 03554 TopoDS_Shape* Shape1 = new TopoDS_Shape(newShape); 03555 shape_list.append(Shape1); 03556 } 03557 else 03558 shape_list.append(topo_face); 03559 is_volume.last(); 03560 is_volume.change_to( CUBIT_FALSE); 03561 } 03562 else if(shells.size() == 1) 03563 { 03564 TopoDS_Shell* topo_shell = shells.get()->get_TopoDS_Shell(); 03565 if(!topo_shell) 03566 { 03567 stat = CUBIT_FAILURE; 03568 break; 03569 } 03570 if(keep_old) 03571 { 03572 BRepBuilderAPI_Copy api_copy(*topo_shell); 03573 TopoDS_Shape newShape = api_copy.ModifiedShape(*topo_shell); 03574 TopoDS_Shape* Shape1 = new TopoDS_Shape(newShape); 03575 shape_list.append(Shape1); 03576 } 03577 else 03578 shape_list.append(topo_shell); 03579 is_volume.change_to( CUBIT_FALSE); 03580 } 03581 03582 else 03583 { 03584 DLIList<Lump*> lumps = occ_body->lumps(); 03585 if (lumps.size() > 1) 03586 { 03587 PRINT_ERROR("Can't do boolean operation on multi-volumes types. \n"); 03588 stat = CUBIT_FAILURE; 03589 break; 03590 } 03591 03592 TopoDS_Solid* solid = CAST_TO(lumps.get(), OCCLump)->get_TopoDS_Solid(); 03593 if(!solid) 03594 { 03595 stat = CUBIT_FAILURE; 03596 break; 03597 } 03598 if(keep_old) 03599 { 03600 BRepBuilderAPI_Copy api_copy(*solid); 03601 TopoDS_Shape newShape = api_copy.ModifiedShape(*solid); 03602 TopoDS_Shape* Shape1 = new TopoDS_Shape(newShape); 03603 shape_list.append(Shape1); 03604 } 03605 else 03606 shape_list.append(solid); 03607 } 03608 } 03609 if(!stat) 03610 { 03611 for (int i = 0; keep_old && i < shape_list.size(); i++) 03612 { 03613 TopoDS_Shape* shape = shape_list.get_and_step(); 03614 delete shape; 03615 shape = NULL; 03616 } 03617 shape_list.clean_out(); 03618 return CUBIT_FAILURE; 03619 } 03620 return CUBIT_SUCCESS; 03621 } 03622 //=============================================================================== 03623 // Function : imprint multiple bodies at once 03624 // Member Type: PUBLIC 03625 // Description: imprint boolean operation on OCC-based bodies 03626 // Author : Jane HU 03627 // Date : 04/08 03628 //=============================================================================== 03629 CubitStatus OCCModifyEngine::imprint(DLIList<BodySM*> &from_body_list , 03630 DLIList<BodySM*> &new_from_body_list, 03631 bool keep_old, 03632 DLIList<TopologyBridge*>* new_tbs, 03633 DLIList<TopologyBridge*>* att_tbs) const 03634 { 03635 CubitStatus success = CUBIT_SUCCESS; 03636 DLIList<TopoDS_Shape*> shape_list; 03637 DLIList<CubitBoolean> is_vo; 03638 03639 //keep record of all vertices and edges and faces in the from_body_list, 03640 //for comparison to generated new_tbs and att_tbs. 03641 DLIList<OCCSurface*> surfaces; 03642 DLIList<OCCCurve*> curves; 03643 DLIList<OCCPoint*> points; 03644 03645 CubitStatus stat = get_shape_list(from_body_list, shape_list, is_vo,keep_old); 03646 03647 if(!stat) 03648 return stat; 03649 03650 int size = shape_list.size(); 03651 // total number of imprints to be done 03652 int total_imprints = size * (size -1); 03653 03654 if( size > 2 ) 03655 { 03656 char message[128]; 03657 sprintf(message, "Imprinting %d OCC Bodies", from_body_list.size() ); 03658 AppUtil::instance()->progress_tool()->start(0, total_imprints, message); 03659 } 03660 03661 std::map<OCCSurface*, std::pair<CubitVector, int> > surf_property_map; 03662 std::map<OCCCurve*, std::pair<CubitVector, int> > curve_property_map; 03663 03664 for(int i = 0; i < size; i++) 03665 { 03666 TopoDS_Shape* shape1 = shape_list[i]; 03667 CubitBoolean modified = CUBIT_FALSE; 03668 03669 DLIList<TopoDS_Face*> face_list; 03670 for(int j = i+1; j < size+i; j ++) 03671 { 03672 if (AppUtil::instance()->interrupt()) 03673 { 03674 success = CUBIT_FAILURE; 03675 break; 03676 } 03677 03678 TopoDS_Shape* shape2 = shape_list[j%size]; 03679 DLIList<TopologyBridge*> tbs; 03680 int result = imprint_toposhapes(shape1, shape2, face_list); 03681 if(result == 0) 03682 { 03683 DLIList<TopologyBridge*> tbs; 03684 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*shape1); 03685 from_body_list[i] = CAST_TO(tbs.get(),BodySM); 03686 modified = CUBIT_TRUE; 03687 } 03688 else if(result == 1) 03689 { 03690 //for cylinder overlapping cases, doing boolean operation is necessary for 03691 //now. 10/25/11 03692 BodySM* tool_copy = copy_body(from_body_list[j%size]); 03693 BodySM* newBody = NULL; 03694 03695 stat = result_1_imprint(from_body_list[i], tool_copy, newBody); 03696 if (stat && newBody) 03697 { 03698 modified = CUBIT_TRUE; 03699 DLIList<TopoDS_Shape*> shapes; 03700 DLIList<CubitBoolean> is_volume; 03701 DLIList<BodySM*> new_bodies; 03702 new_bodies.append(newBody); 03703 get_shape_list(new_bodies, shapes, is_volume,false); 03704 shape1 = shapes.get(); 03705 //shape_list[i] = shape1; 03706 from_body_list[i] = newBody; 03707 } 03708 } 03709 else if(result == 3) 03710 { 03711 BodySM* newBody = NULL; 03712 BodySM* oldBody = from_body_list[i]; 03713 TopExp_Explorer Ex; 03714 Ex.Init(*shape1, TopAbs_SOLID); 03715 int nSolid = 0; 03716 for(; Ex.More(); Ex.Next()) 03717 nSolid++; 03718 do 03719 { 03720 TopoDS_Face* face = face_list.pop(); 03721 int k = OCCQueryEngine::instance()->OCCMap->Find(*face); 03722 OCCSurface* cut_face = (OCCSurface*)(OCCQueryEngine::instance()->OccToCGM->find(k))->second; 03723 OCCBody* tool_body = cut_face->my_body(); 03724 03725 stat = result_3_imprint(oldBody, tool_body, newBody); 03726 if (newBody) 03727 { 03728 modified = CUBIT_TRUE; 03729 DLIList<TopoDS_Shape*> shapes; 03730 DLIList<CubitBoolean> is_volume; 03731 DLIList<BodySM*> new_bodies; 03732 new_bodies.append(newBody); 03733 get_shape_list(new_bodies, shapes, is_volume,false); 03734 shape1 = shapes.get(); 03735 //shape_list[i] = shape1; 03736 from_body_list[i] = newBody; 03737 } 03738 if(nSolid == 1) 03739 break; 03740 else 03741 nSolid --; 03742 result = imprint_toposhapes(shape1, shape2, face_list); 03743 oldBody = newBody; 03744 }while (result == 3); 03745 } 03746 } 03747 if(modified) 03748 new_from_body_list.append(from_body_list[i]); 03749 03750 shape_list.reset(); 03751 if( size > 2 ) 03752 AppUtil::instance()->progress_tool()->step(); 03753 } 03754 03755 if( size > 2 ) 03756 AppUtil::instance()->progress_tool()->end(); 03757 03758 if( AppUtil::instance()->interrupt() ) 03759 PRINT_INFO("Imprint aborted.\n"); 03760 03761 return success; 03762 } 03763 03764 CubitStatus OCCModifyEngine::result_3_imprint(BodySM* from_body, 03765 BodySM* tool_body, 03766 BodySM*& newBody)const 03767 { 03768 DLIList<BodySM*> from_bodies; 03769 from_bodies.append(from_body); 03770 DLIList<BodySM*> results_list; 03771 DLIList<BodySM*> neighbor_imprint_list; 03772 CubitStatus stat = webcut(from_bodies, tool_body, neighbor_imprint_list, 03773 results_list); 03774 if(results_list.size() > 1) 03775 { 03776 DLIList<BodySM*> bodies; 03777 unite(results_list, bodies, false); 03778 newBody = bodies.get(); 03779 } 03780 else if (results_list.size() == 1) 03781 newBody = results_list.get(); 03782 03783 return stat; 03784 03785 } 03786 03787 CubitStatus OCCModifyEngine::result_1_imprint(BodySM* from_body, 03788 BodySM* tool_body, 03789 BodySM*& newBody)const 03790 { 03791 //for compound of solids in from_body, try to determine if subtracting or 03792 //intersecting will keep the from_body un-deleted by checking subtracting 03793 //first, if it kept the from_body, don't take any further risk, do intersect 03794 //first, then subtract. 03795 03796 DLIList<TopoDS_Shape*> from_bodies_shapes; 03797 DLIList<BodySM*> from_bodies ; 03798 DLIList<CubitBoolean> is_volume; 03799 from_bodies.append(from_body); 03800 //get the from_bodies underling shapes 03801 CubitStatus stat = get_shape_list(from_bodies, from_bodies_shapes, is_volume, CUBIT_FALSE); 03802 03803 TopoDS_Shape* from_shape = from_bodies_shapes.get(); 03804 int num_solids = 0; 03805 if(from_shape->ShapeType() == TopAbs_COMPOUND) 03806 { 03807 TopExp_Explorer Ex; 03808 for (Ex.Init(*from_shape, TopAbs_SOLID);Ex.More(); Ex.Next()) 03809 num_solids++; 03810 } 03811 BodySM* tool_copy = copy_body(tool_body); 03812 DLIList<BodySM*> tools; 03813 tools.append(tool_copy); 03814 from_bodies.clean_out() ; 03815 BodySM* from_copy = copy_body(from_body); 03816 from_bodies.append(from_copy); 03817 DLIList<BodySM*> new_bodies; 03818 stat = subtract(tools, from_bodies, new_bodies, false, false); 03819 if (stat) 03820 { 03821 if (num_solids > 1 && from_copy == new_bodies.get()) 03822 { 03823 //double check if subtract kept the original from_bodies pointer. 03824 //if so, do intersect first, then subtract. 03825 tool_copy = copy_body(tool_body); 03826 from_bodies.clean_out(); 03827 from_copy = copy_body(from_body); 03828 from_bodies.append(from_copy); 03829 OCCQueryEngine::instance()->delete_solid_model_entities(new_bodies); 03830 new_bodies.clean_out(); 03831 intersect(tool_copy, from_bodies, new_bodies, false); 03832 03833 tool_copy = copy_body(tool_body); 03834 tools.clean_out(); 03835 tools.append(tool_copy); 03836 from_bodies.clean_out(); 03837 from_bodies.append(from_body); 03838 subtract(tools, from_bodies, new_bodies, false, false); 03839 } 03840 else 03841 { 03842 tool_copy = copy_body(tool_body); 03843 from_bodies.clean_out(); 03844 from_bodies.append(from_body); 03845 intersect(tool_copy, from_bodies, new_bodies, false); 03846 } 03847 03848 //make sure the first body in new_bodies is the one we want to keep. 03849 new_bodies.reverse(); 03850 if(new_bodies.size() > 1) 03851 { 03852 DLIList<BodySM*> final_bodies; 03853 unite(new_bodies, final_bodies, false); 03854 new_bodies.clean_out(); 03855 new_bodies = final_bodies; 03856 } 03857 newBody = new_bodies.get(); 03858 } 03859 return stat; 03860 } 03861 03862 //=============================================================================== 03863 // Function : imprint 03864 // Member Type: PUBLIC 03865 // Description: imprint curves onto body_list 03866 // Author : Jane Hu 03867 // Date : 05/08 03868 //=============================================================================== 03869 CubitStatus OCCModifyEngine::imprint( DLIList<BodySM*> &body_list, 03870 DLIList<Curve*> &ref_edge_list, 03871 DLIList<BodySM*>& new_body_list, 03872 DLIList<TopologyBridge*> &temp_bridges, 03873 bool keep_old, 03874 bool show_messages) const 03875 { 03876 CubitStatus success = CUBIT_SUCCESS; 03877 DLIList<TopoDS_Shape*> shape_list, tool_shapes; 03878 DLIList<CubitBoolean> is_vo; 03879 CubitStatus stat = get_shape_list(body_list, shape_list, is_vo, keep_old); 03880 if (!stat) 03881 return stat; 03882 03883 int size = ref_edge_list.size(); 03884 // total number of imprints to be done 03885 03886 if( size > 2 && show_messages) 03887 { 03888 char message[128]; 03889 sprintf(message, "Imprinting %d OCC Bodies", body_list.size() ); 03890 AppUtil::instance()->progress_tool()->start(0, size, message); 03891 } 03892 for (int i = 0; i < ref_edge_list.size(); i++) 03893 { 03894 OCCCurve* curve = CAST_TO(ref_edge_list.get_and_step(), OCCCurve) ; 03895 if (!curve) 03896 continue; 03897 03898 TopoDS_Edge* edge = curve->get_TopoDS_Edge(); 03899 if (edge->IsNull()) 03900 continue; 03901 03902 if (AppUtil::instance()->interrupt()) 03903 { 03904 success = CUBIT_FAILURE; 03905 break; 03906 } 03907 DLIList<TopoDS_Face*> face_list; 03908 for(int j = 0; j < shape_list.size(); j ++) 03909 { 03910 TopoDS_Shape* shape = shape_list.get(); 03911 03912 int result = imprint_toposhapes(shape, (TopoDS_Shape*)edge, face_list); 03913 if (result == 0) 03914 shape_list.change_to(shape); 03915 shape_list.step(); 03916 body_list.step(); 03917 } 03918 03919 if( size > 2 ) 03920 AppUtil::instance()->progress_tool()->step(); 03921 } 03922 03923 for(int j = 0; j < shape_list.size(); j ++) 03924 { 03925 DLIList<TopologyBridge*> tbs; 03926 TopoDS_Shape* shape = shape_list.get_and_step(); 03927 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*shape); 03928 new_body_list.append(CAST_TO(tbs.get(),BodySM)); 03929 } 03930 03931 if( size > 2 ) 03932 AppUtil::instance()->progress_tool()->end(); 03933 03934 if( AppUtil::instance()->interrupt() ) 03935 PRINT_INFO("Imprint aborted.\n"); 03936 return success; 03937 } 03938 03939 //=============================================================================== 03940 // Function : imprint 03941 // Member Type: PUBLIC 03942 // Description: to be consistante with imprint. 03943 // The surfaces must be part of a body, but the curves 03944 // just have to be valid OCC edge. 03945 // Author : Jane Hu 03946 // Date : 05/08 03947 //=============================================================================== 03948 CubitStatus OCCModifyEngine::imprint( DLIList<Surface*> &ref_face_list, 03949 DLIList<Curve*> &edge_list, 03950 DLIList<TopologyBridge*> &temp_bridges, 03951 DLIList<BodySM*>& new_body_list, 03952 bool keep_old) const 03953 { 03954 DLIList<TopoDS_Face*> face_list; 03955 DLIList<TopoDS_Shape*> shape_list; 03956 03957 face_edge_imprint(ref_face_list, edge_list, face_list, shape_list, keep_old); 03958 03959 TopExp_Explorer Ex; 03960 int num_face = 0; 03961 TopoDS_Shape* shape = shape_list.get_and_step(); 03962 for (Ex.Init(*shape, TopAbs_FACE); Ex.More(); Ex.Next()) 03963 { 03964 TopoDS_Face face = TopoDS::Face(Ex.Current()); 03965 num_face++; 03966 } 03967 03968 for(int j = 0; j < shape_list.size(); j ++) 03969 { 03970 DLIList<TopologyBridge*> tbs; 03971 TopoDS_Shape* shape = shape_list.get_and_step(); 03972 if (!shape || shape->IsNull()) 03973 continue; 03974 if (shape->ShapeType() == TopAbs_COMPOUND) 03975 { 03976 if(!OCCQueryEngine::instance()->OCCMap->IsBound(*shape)) 03977 { 03978 TopExp_Explorer Ex; 03979 for (Ex.Init(*shape, TopAbs_SOLID);Ex.More(); Ex.Next()) 03980 { 03981 TopoDS_Shape subshape = Ex.Current(); 03982 tbs += OCCQueryEngine::instance()->populate_topology_bridge(subshape); 03983 new_body_list.append_unique(CAST_TO(tbs.get(),BodySM)); 03984 } 03985 } 03986 } 03987 else 03988 { 03989 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*shape); 03990 new_body_list.append_unique(CAST_TO(tbs.get(),BodySM)); 03991 } 03992 } 03993 03994 /* 03995 if (keep_old) 03996 { 03997 for(int i = 0; i < face_list.size(); i++) 03998 { 03999 TopoDS_Face* face = face_list.get(); 04000 face->Nullify(); 04001 delete face; 04002 face =NULL; 04003 } 04004 } 04005 */ 04006 return CUBIT_SUCCESS; 04007 } 04008 04009 //=============================================================================== 04010 // Function : face_edge_imprint 04011 // Member Type: PRIVATE 04012 // Description: to be consistante with imprint. 04013 // The surfaces must be part of a body, but the curves 04014 // just have to be valid OCC edge. 04015 // Author : Jane Hu 04016 // Date : 05/08 04017 //=============================================================================== 04018 CubitStatus 04019 OCCModifyEngine::face_edge_imprint( DLIList<Surface*> &ref_face_list, 04020 DLIList<Curve*> &edge_list, 04021 DLIList<TopoDS_Face*>& face_list, 04022 DLIList<TopoDS_Shape*>& shape_list, 04023 bool keep_old ) const 04024 { 04025 for(int i = 0; i <ref_face_list.size(); i++) 04026 { 04027 OCCSurface* surface = CAST_TO(ref_face_list.get_and_step(), OCCSurface); 04028 if(!surface) 04029 continue; 04030 04031 TopoDS_Face* topo_face = surface->get_TopoDS_Face(); 04032 face_list.append(topo_face); 04033 04034 OCCBody* occ_body = NULL; 04035 OCCShell* shell = surface->my_shell(); 04036 if(shell && shell->my_body()) 04037 occ_body = shell->my_body(); 04038 else 04039 { 04040 DLIList<OCCBody*> bodies; 04041 surface->get_bodies(bodies); 04042 if(bodies.size() != 1) 04043 { 04044 PRINT_ERROR("Can't find the corresponding manifold solid body.\n"); 04045 return CUBIT_FAILURE; 04046 } 04047 occ_body = bodies.get(); 04048 } 04049 TopoDS_Shape *shape ; 04050 occ_body->get_TopoDS_Shape(shape); 04051 04052 if(shape && !shape->IsNull()) 04053 shape_list.append_unique(shape); 04054 } 04055 04056 if(keep_old) 04057 { 04058 for(int i = 0; i < shape_list.size(); i++) 04059 { 04060 TopoDS_Shape* shape = shape_list.get(); 04061 BRepBuilderAPI_Copy api_copy(*shape); 04062 TopoDS_Shape newShape = api_copy.ModifiedShape(*shape); 04063 TopoDS_Shape* Shape1 = new TopoDS_Shape(newShape); 04064 for(int j = 0; j < face_list.size(); j++) 04065 { 04066 TopoDS_Face* face = face_list.get(); 04067 TopExp_Explorer Ex, Ex_new; 04068 for (Ex.Init(*shape, TopAbs_FACE); Ex.More(); Ex.Next()) 04069 { 04070 if(face->IsSame(Ex.Current())) 04071 { 04072 face = new TopoDS_Face(TopoDS::Face(api_copy.ModifiedShape(*face))); 04073 face_list.change_to(face); 04074 } 04075 } 04076 face_list.step(); 04077 } 04078 shape_list.change_to(Shape1); 04079 shape_list.step(); 04080 } 04081 } 04082 04083 for (int i = 0; i < edge_list.size(); i++) 04084 { 04085 OCCCurve* curve = CAST_TO(edge_list.get_and_step(), OCCCurve) ; 04086 if (!curve) 04087 continue; 04088 04089 TopoDS_Edge* edge = curve->get_TopoDS_Edge(); 04090 if (edge->IsNull()) 04091 continue; 04092 04093 for(int j = 0; j < shape_list.size(); j ++) 04094 { 04095 TopoDS_Shape* shape = shape_list.get_and_step(); 04096 DLIList<TopoDS_Face*> record_faces; 04097 for (int e = 0; e < face_list.size(); e++) 04098 record_faces.append(face_list.get_and_step()); 04099 04100 imprint_toposhapes(shape, (TopoDS_Shape*)edge, face_list); 04101 for (int e = 0; e < record_faces.size()&& keep_old; e++) 04102 { 04103 TopoDS_Face* test_face = record_faces.get_and_step(); 04104 if(!face_list.move_to(test_face)) 04105 { 04106 test_face->Nullify(); 04107 delete test_face; 04108 } 04109 } 04110 } 04111 } 04112 04113 for(int j = 0; keep_old && j < face_list.size(); j++) 04114 { 04115 TopoDS_Face* face = face_list.get_and_step(); 04116 face->Nullify(); 04117 delete face; 04118 } 04119 04120 TopExp_Explorer Ex; 04121 int num_face = 0; 04122 TopoDS_Shape* shape = shape_list.get_and_step(); 04123 for (Ex.Init(*shape, TopAbs_FACE); Ex.More(); Ex.Next()) 04124 { 04125 TopoDS_Face face = TopoDS::Face(Ex.Current()); 04126 num_face++; 04127 } 04128 04129 return CUBIT_SUCCESS; 04130 } 04131 //=============================================================================== 04132 // Function : imprint 04133 // Member Type: PUBLIC 04134 // Description: To be consistent with ModifyEngine, althought it's hard 04135 // to have a GUI interface for users to input. All surface must 04136 // on the same body. 04137 // Author : Jane HU 04138 // Date : 06/08 04139 //=============================================================================== 04140 CubitStatus OCCModifyEngine::imprint( DLIList<Surface*>& surface_list, 04141 DLIList<DLIList<Curve*>*>& curve_lists_list, 04142 BodySM*& new_body, 04143 bool keep_old, 04144 bool expand, 04145 DLIList<TopologyBridge*> *new_tbs, 04146 DLIList<TopologyBridge*> *att_tbs ) const 04147 { 04148 DLIList<TopoDS_Face*> face_list; 04149 DLIList<TopoDS_Shape*> shape_list; 04150 DLIList<TopoDS_Shape*> shape_list_all; 04151 DLIList<OCCSurface*> surfaces; 04152 DLIList<OCCCurve*> curves; 04153 DLIList<OCCPoint*> points; 04154 04155 assert (surface_list.size() == curve_lists_list.size()); 04156 DLIList<OCCBody*> bodies; 04157 04158 std::map<OCCSurface*, std::pair<CubitVector, double> > surf_property_map; 04159 std::map<OCCCurve*, std::pair<CubitVector, double> > curve_property_map; 04160 04161 for(int j = 0; j < surface_list.size(); j++) 04162 { 04163 Surface* surface = surface_list.get_and_step(); 04164 04165 //keep record of old bodies, surfaces, curves and points 04166 OCCSurface* occ_surface = CAST_TO(surface, OCCSurface); 04167 occ_surface->get_bodies(bodies); 04168 if(j == 0) 04169 { 04170 bodies.get()->get_all_surfaces(surfaces); 04171 bodies.get()->get_all_curves(curves); 04172 bodies.get()->get_all_points(points); 04173 04174 //save surface with its area and center info in the map 04175 for(int i = 0; i < surfaces.size(); i++) 04176 { 04177 OCCSurface* surf = CAST_TO(surfaces.get(), OCCSurface); 04178 double d = surf->measure(); 04179 CubitVector center = surf->center_point(); 04180 surf_property_map.insert(valType 04181 (surf, std::pair<CubitVector, double>(center,d))); 04182 } 04183 04184 //save curve with its length and center info in the map 04185 for(int i = 0; i < curves.size(); i++) 04186 { 04187 OCCCurve* curve = CAST_TO(curves.get(), OCCCurve); 04188 double d = curve->measure(); 04189 CubitVector center = curve->center_point(); 04190 curve_property_map.insert(valType2 04191 (curve, std::pair<CubitVector, double>(center,d))); 04192 } 04193 } 04194 DLIList<Surface*> ref_face_list; 04195 ref_face_list.append(surface); 04196 DLIList<Curve*> *edge_list = curve_lists_list.get_and_step(); 04197 face_edge_imprint(ref_face_list, *edge_list, face_list, shape_list, keep_old); 04198 04199 for(int i = 0; i < shape_list.size(); i++) 04200 { 04201 TopoDS_Shape* shape = shape_list.get_and_step(); 04202 shape_list_all.append_unique(shape); 04203 } 04204 shape_list.clean_out(); 04205 04206 if (keep_old) 04207 { 04208 for(int i = 0; i < face_list.size(); i++) 04209 { 04210 TopoDS_Face* face = face_list.get(); 04211 face->Nullify(); 04212 delete face; 04213 face = NULL; 04214 } 04215 } 04216 04217 face_list.clean_out(); 04218 } 04219 04220 assert (bodies.size() == 1); 04221 04222 DLIList<BodySM*> new_body_list; 04223 shape_to_bodySM(shape_list, new_body_list); 04224 04225 if (new_body_list.size() == 1) 04226 { 04227 new_body = new_body_list.get(); 04228 //find new_tbs and att_tbs; 04229 DLIList<OCCSurface*> new_surfs; 04230 DLIList<OCCCurve*> new_curves; 04231 DLIList<OCCPoint*> new_points; 04232 if(new_tbs || att_tbs) 04233 { 04234 OCCBody* occ_body = CAST_TO(new_body, OCCBody); 04235 occ_body->get_all_surfaces(new_surfs); 04236 occ_body->get_all_curves(new_curves); 04237 occ_body->get_all_points(new_points); 04238 } 04239 if(new_tbs) 04240 get_new_tbs(surf_property_map, curve_property_map, points, new_surfs, 04241 new_curves, new_points, new_tbs); 04242 if(att_tbs) 04243 get_att_tbs(new_surfs, new_curves, new_points, "COMPOSITE_GEOM", 04244 att_tbs); 04245 04246 return CUBIT_SUCCESS; 04247 } 04248 return CUBIT_FAILURE; 04249 } 04250 04251 //=============================================================================== 04252 // Function : shape_to_bodySM 04253 // Member Type: PRIVATE 04254 // Description: After imprint, update shape list to bodySM_list 04255 // Author : Jane Hu 04256 // Date : 06/08 04257 //=============================================================================== 04258 void OCCModifyEngine::shape_to_bodySM( DLIList<TopoDS_Shape*> shape_list, 04259 DLIList<BodySM*>& new_body_list)const 04260 { 04261 for(int j = 0; j < shape_list.size(); j ++) 04262 { 04263 DLIList<TopologyBridge*> tbs; 04264 TopoDS_Shape* shape = shape_list.get_and_step(); 04265 if (shape->ShapeType() == TopAbs_COMPOUND) 04266 { 04267 if(!OCCQueryEngine::instance()->OCCMap->IsBound(*shape)) 04268 { 04269 TopExp_Explorer Ex; 04270 for (Ex.Init(*shape, TopAbs_SOLID);Ex.More(); Ex.Next()) 04271 { 04272 TopoDS_Shape subshape = Ex.Current(); 04273 tbs += OCCQueryEngine::instance()->populate_topology_bridge(subshape); 04274 new_body_list.append_unique(CAST_TO(tbs.get(),BodySM)); 04275 } 04276 } 04277 } 04278 else 04279 { 04280 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*shape); 04281 BodySM* body = CAST_TO(tbs.get(),BodySM); 04282 if(body != NULL) 04283 new_body_list.append_unique(body); 04284 } 04285 } 04286 } 04287 04288 //=============================================================================== 04289 // Function : imprint 04290 // Member Type: PUBLIC 04291 // Description: Imprints locations to bodies (for splitting curves, there's 04292 // no known ways to put hard points on surfaces in OCC, so I just 04293 // add free_vertex on OCCSurface definition, mesh should look on 04294 // this structure). 04295 // Author : Jane Hu 04296 // Date : 06/08 04297 //=============================================================================== 04298 CubitStatus OCCModifyEngine::imprint( DLIList<BodySM*> &body_list, 04299 DLIList<CubitVector> &vector_list, 04300 DLIList<BodySM*>& new_body_list, 04301 bool keep_old, 04302 DLIList<TopologyBridge*>* new_tbs, 04303 DLIList<TopologyBridge*>* att_tbs, 04304 double *tol_in , 04305 bool clean_up_slivers ) const 04306 { 04307 DLIList<TopoDS_Shape*> shape_list; 04308 DLIList<CubitBoolean> is_vo; 04309 double tol = 0.1; 04310 if(tol_in) 04311 tol = *tol_in; 04312 CubitStatus stat = get_shape_list(body_list, shape_list, is_vo, keep_old); 04313 if(!stat) 04314 return stat; 04315 04316 for (int i = 0; i < body_list.size(); i++) 04317 { 04318 OCCBody* body = CAST_TO(body_list.get_and_step(), OCCBody); 04319 TopoDS_Shape* from_shape = shape_list.get(); 04320 if (!body) 04321 continue; 04322 DLIList<OCCSurface*> surfaces; 04323 DLIList<OCCCurve*> curves; 04324 04325 body->get_all_surfaces(surfaces); 04326 body->get_all_curves(curves); 04327 04328 CubitBoolean on_vertex = CUBIT_FALSE; 04329 CubitBoolean on_curve = CUBIT_FALSE; 04330 for (int j = 0; j < vector_list.size(); j ++) 04331 { 04332 CubitVector& v = vector_list[j]; 04333 for (int k = 0; k < curves.size(); k ++) 04334 { 04335 OCCCurve* curve = curves.get_and_step(); 04336 CubitPointContainment pc = curve->point_containment(v); 04337 if(pc == CUBIT_PNT_BOUNDARY) 04338 { 04339 on_vertex = CUBIT_TRUE; 04340 break; 04341 } 04342 04343 else if( pc == CUBIT_PNT_INSIDE) 04344 { 04345 on_curve = CUBIT_TRUE; 04346 //first make sure it won't generate a sliver curve 04347 //with respect to tol. 04348 if(clean_up_slivers) 04349 { 04350 double u = curve->u_from_position(v); 04351 double u_min, u_max; 04352 curve->get_param_range(u_min, u_max); 04353 double l1 = curve->length_from_u(u_min, u); 04354 double l2 = curve->measure() - l1; 04355 if(l1 <= tol || l2 <= tol) 04356 break; 04357 } 04358 04359 const CubitVector location = v; 04360 DLIList<Curve*> created_curves; 04361 stat = split_shape_by_location(from_shape, (Curve*)curve, location, 04362 created_curves); 04363 shape_list.change_to(from_shape); 04364 if(new_tbs) 04365 for(int ic=0; ic < created_curves.size(); ic++) 04366 new_tbs->append(created_curves.get_and_step()); 04367 04368 curves.remove(curve); 04369 for(int ic = 0; ic < created_curves.size(); ic++) 04370 curves.append(CAST_TO(created_curves.get_and_step(), OCCCurve)); 04371 break; 04372 } 04373 } 04374 if(on_vertex || on_curve) 04375 continue; 04376 04377 //check possible on surface 04378 for(int n = 0; n < surfaces.size(); n ++) 04379 { 04380 OCCSurface* surface = surfaces.get_and_step(); 04381 if(!surface->is_position_on(v)) 04382 continue; 04383 04384 CubitPointContainment ps = surface->point_containment(v); 04385 if(ps == CUBIT_PNT_INSIDE) 04386 { 04387 TBPoint* p = make_Point(v); 04388 if(p) 04389 { 04390 surface->add_hardpoint(CAST_TO(p, OCCPoint)); 04391 if(new_tbs) 04392 new_tbs->append(p); 04393 } 04394 break; 04395 } 04396 } 04397 } 04398 shape_list.step(); 04399 } 04400 04401 shape_to_bodySM(shape_list, new_body_list); 04402 04403 DLIList<OCCSurface*> surfaces; 04404 DLIList<OCCCurve*> curves; 04405 DLIList<OCCPoint*> points; 04406 for (int i = 0; i < new_body_list.size(); i++) 04407 { 04408 OCCBody * body = CAST_TO(new_body_list.get_and_step(), OCCBody); 04409 body->get_all_surfaces(surfaces); 04410 body->get_all_curves(curves); 04411 body->get_all_points(points); 04412 } 04413 04414 get_att_tbs(surfaces, curves, points, "COMPOSITE_GEOM", att_tbs); 04415 04416 return stat; 04417 } 04418 04419 04420 //=============================================================================== 04421 // Function : imprint_projected_edges 04422 // Member Type: PUBLIC 04423 // Description: Projects a list of Curves on to a list of Surfaces 04424 // and imprint the faces with the new Curves 04425 // Author : Jane Hu 04426 // Date : 06/08 04427 //=============================================================================== 04428 CubitStatus 04429 OCCModifyEngine::imprint_projected_edges( DLIList<Surface*> &ref_face_list, 04430 DLIList<Curve*> &ref_edge_list, 04431 DLIList<BodySM*>& new_body_list, 04432 DLIList<Curve*>& kept_free_edges, 04433 bool keep_old_body, 04434 bool keep_free_edges) const 04435 { 04436 DLIList<Curve*> projected_curves; 04437 CubitStatus 04438 stat = project_edges(ref_face_list, ref_edge_list, projected_curves); 04439 if(!stat) 04440 return stat; 04441 04442 // imprint Surface with curves 04443 DLIList<TopologyBridge*> temp_bridges; 04444 stat = imprint(ref_face_list, projected_curves, temp_bridges, new_body_list, keep_old_body ); 04445 04446 if(keep_free_edges) 04447 { 04448 kept_free_edges += projected_curves; 04449 return stat; 04450 } 04451 04452 PRINT_INFO( "Removing projected curves \n"); 04453 for(int i=0; i< projected_curves.size();i++) 04454 { 04455 // Now delete this Curve and its underlying solid model entities 04456 04457 Curve* curve = projected_curves.get_and_step(); 04458 stat = OCCQueryEngine::instance()->delete_solid_model_entities( curve ); 04459 if (stat == CUBIT_FAILURE) 04460 { 04461 PRINT_ERROR("In OCCQueryEngine::delete_geometry\n" 04462 " Could not delete OCCCurve.\n" 04463 " The Model database is likely corrupted " 04464 "due to\n this unsuccessful deletion.\n" ); 04465 } 04466 } 04467 return stat; 04468 } 04469 //=============================================================================== 04470 // Function : project_edges 04471 // Member Type: PUBLIC 04472 // Description: Projects a list of Curves on to a list of Surfaces 04473 // Author : Jane Hu 04474 // Date : 06/08 04475 //=============================================================================== 04476 CubitStatus OCCModifyEngine::project_edges( DLIList<Surface*> &ref_face_list, 04477 DLIList<Curve*> &ref_edge_list, 04478 DLIList<Curve*> &projected_curves, 04479 bool print_error ) const 04480 04481 { 04482 CubitVector* v = NULL; 04483 Curve* projected_curve = NULL; 04484 DLIList<TBPoint*> points; 04485 //project curves onto surfaces. 04486 for(int i = 0; i < ref_edge_list.size(); i++) 04487 { 04488 OCCCurve* curve = CAST_TO(ref_edge_list.get_and_step(), OCCCurve); 04489 if(!curve) 04490 continue; 04491 04492 for (int j = 0; j < ref_face_list.size(); j++) 04493 { 04494 OCCSurface* surface = CAST_TO(ref_face_list.get_and_step(), OCCSurface); 04495 if(!surface) 04496 continue; 04497 if(surface->is_closed_in_U() || surface->is_closed_in_V()) 04498 { 04499 if(print_error) 04500 PRINT_ERROR("This function can't project curves on closed surfaces.\n"); 04501 return CUBIT_FAILURE; 04502 } 04503 04504 projected_curve = NULL; 04505 projected_curve = curve->project_curve(surface, points, CUBIT_FALSE, v); 04506 if(projected_curve) 04507 projected_curves.append_unique(projected_curve); 04508 } 04509 } 04510 while(points.size() > 0) 04511 delete points.pop(); 04512 return CUBIT_SUCCESS; 04513 } 04514 04515 //=============================================================================== 04516 // Function : imprint_projected_edges 04517 // Member Type: PUBLIC 04518 // Description: Projects a list of curves on to a list of surfaces 04519 // and imprint the bodies with the new curves 04520 // Author : Jane Hu 04521 // Date : 06/08 04522 //=============================================================================== 04523 CubitStatus 04524 OCCModifyEngine::imprint_projected_edges(DLIList<Surface*> &ref_face_list, 04525 DLIList<BodySM*> &body_list, 04526 DLIList<Curve*> &ref_edge_list, 04527 DLIList<BodySM*>& new_body_list, 04528 bool keep_old, 04529 bool keep_free_edges) const 04530 { 04531 DLIList<Curve*> projected_curves; 04532 CubitStatus 04533 stat = project_edges(ref_face_list, ref_edge_list, projected_curves); 04534 if(!stat) 04535 return stat; 04536 return CUBIT_FAILURE; 04537 04538 // imprint bodies with curves 04539 DLIList<TopologyBridge*> temp_bridges; 04540 stat = imprint(body_list,projected_curves, new_body_list, temp_bridges, keep_old); 04541 04542 if (keep_free_edges) 04543 return stat; 04544 04545 PRINT_INFO( "Removing projected curves \n"); 04546 for(int i=0; i< projected_curves.size();i++) 04547 { 04548 // Now delete this Curve 04549 Curve* curve = projected_curves.get_and_step(); 04550 stat = OCCQueryEngine::instance()-> 04551 delete_solid_model_entities( curve ); 04552 if (stat == CUBIT_FAILURE) 04553 { 04554 PRINT_ERROR("In OCCModifyEngine::delete_geometry\n" 04555 " Could not delete Curve.\n" 04556 " The Model database is likely corrupted " 04557 "due to\n this unsuccessful deletion.\n" ); 04558 } 04559 } 04560 return stat; 04561 } 04562 04563 //=============================================================================== 04564 // Function : intersect 04565 // Member Type: PUBLIC 04566 // Description: intersect boolean operation of body with list of bodies. 04567 // Author : Jane Hu 04568 // Date : 06/08 04569 //=============================================================================== 04570 CubitStatus OCCModifyEngine::intersect(BodySM* tool_body_ptr, 04571 DLIList<BodySM*> &from_bodies, 04572 DLIList<BodySM*> &new_bodies, 04573 bool keep_old, 04574 bool preview) const 04575 { 04576 DLIList<BodySM*> tool_bodies; 04577 DLIList<TopoDS_Shape*> tool_shapes; 04578 DLIList<CubitBoolean> is_tool_volume, is_volume; 04579 04580 tool_bodies.append(tool_body_ptr); 04581 //get tool_body's underlying shape, copy it, so boolean wouldn't touch it. 04582 CubitStatus stat = 04583 get_shape_list(tool_bodies, tool_shapes, is_tool_volume, CUBIT_TRUE); 04584 if(!stat) 04585 return stat; 04586 04587 DLIList<TopoDS_Shape*> shape_list; 04588 stat = get_shape_list(from_bodies, shape_list, is_volume, keep_old); 04589 if(!stat) 04590 { 04591 for (int i = 0; i < tool_shapes.size(); i++) 04592 { 04593 TopoDS_Shape* shape = tool_shapes.get_and_step(); 04594 delete shape; 04595 shape = NULL; 04596 } 04597 tool_shapes.clean_out(); 04598 return CUBIT_FAILURE; 04599 } 04600 04601 TopoDS_Shape* tool_shape = tool_shapes.get(); 04602 CubitBoolean has_changed; 04603 DLIList<TopologyBridge*> tbs; 04604 DLIList<TopoDS_Shape*> preview_list; 04605 for (int i = 0; i < shape_list.size(); i++) 04606 { 04607 TopoDS_Shape* from_shape = shape_list.get_and_step(); 04608 BodySM* from_body = from_bodies.get_and_step(); 04609 BRepAlgoAPI_Common intersector(*from_shape, *tool_shape); 04610 04611 TopTools_ListOfShape shapes; 04612 shapes.Assign(intersector.Modified(*tool_shape)); 04613 04614 if ( shapes.Extent() > 1) 04615 { 04616 PRINT_ERROR("Tool has multiple intersection with the shape, make it simpler. \n"); 04617 continue; 04618 } 04619 TopoDS_Shape common_shape; 04620 if (shapes.IsEmpty()) 04621 common_shape = intersector.Shape(); 04622 else 04623 common_shape = shapes.First(); 04624 04625 if (!common_shape.IsNull()) 04626 { 04627 TopExp_Explorer Ex(common_shape, TopAbs_SOLID); 04628 if(!Ex.More() && is_volume[i] == CUBIT_TRUE && 04629 common_shape.ShapeType() > TopAbs_SOLID) 04630 { 04631 has_changed = CUBIT_TRUE; 04632 *from_shape = common_shape; 04633 } 04634 04635 else if (is_volume[i] == CUBIT_FALSE && 04636 common_shape.ShapeType() > TopAbs_FACE) 04637 { 04638 Ex.Init(common_shape, TopAbs_SHELL, TopAbs_SOLID); 04639 if(!Ex.More()) 04640 Ex.Init(common_shape, TopAbs_FACE); 04641 if(!Ex.More() && is_volume[i] == CUBIT_FALSE) 04642 { 04643 has_changed = CUBIT_TRUE; 04644 *from_shape = common_shape; 04645 } 04646 } 04647 else 04648 { 04649 double after_mass = 0.0; 04650 GProp_GProps myProps; 04651 if(is_volume[i]) 04652 BRepGProp::VolumeProperties(common_shape, myProps); 04653 04654 else 04655 BRepGProp::SurfaceProperties(common_shape, myProps); 04656 after_mass = myProps.Mass(); 04657 if(after_mass > TOL) 04658 check_operation(common_shape, from_shape, is_volume[i], has_changed, 04659 &intersector, keep_old); 04660 else 04661 { 04662 if(!keep_old) 04663 OCCQueryEngine::instance()->delete_solid_model_entities(from_body); 04664 from_shape = NULL; 04665 } 04666 } 04667 } 04668 04669 if(from_shape == NULL || from_shape->IsNull() ) 04670 { 04671 PRINT_INFO("The %d body did not have common part with the tool_body.\n", i+1); 04672 } 04673 else 04674 { 04675 if(preview) 04676 { 04677 TopoDS_Shape* p_shape = new TopoDS_Shape(common_shape); 04678 preview_list.append(p_shape); 04679 } 04680 else 04681 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*from_shape); 04682 } 04683 } 04684 04685 if(preview) 04686 { 04687 GfxPreview::clear(); 04688 for(int i = 0; i < preview_list.size(); i++) 04689 { 04690 TopoDS_Shape* new_shape = preview_list.get_and_step(); 04691 // Draw this face 04692 OCCDrawTool::instance()->draw_TopoDS_Shape( new_shape, CUBIT_BLUE_INDEX, 04693 CUBIT_FALSE, CUBIT_TRUE ); 04694 delete new_shape; 04695 } 04696 } 04697 04698 for (int i = 0; i< tbs.size(); i++) 04699 { 04700 BodySM* bodysm = CAST_TO(tbs.get_and_step(), BodySM); 04701 if (bodysm) 04702 new_bodies.append(bodysm); 04703 } 04704 04705 //if(tbs.size() == 0) 04706 // stat = CUBIT_FAILURE; 04707 04708 //ok, we're done with all cuts, delete unnecessaries. 04709 if(!keep_old) 04710 OCCQueryEngine::instance()->delete_solid_model_entities(tool_body_ptr); 04711 04712 for(int i = 0; i < tool_shapes.size(); i++) 04713 { 04714 TopoDS_Shape* shape = tool_shapes.get_and_step(); 04715 shape->Nullify(); 04716 delete shape; 04717 shape = NULL; 04718 } 04719 04720 if(keep_old) 04721 { 04722 int size = shape_list.size(); 04723 for (int i = 0; i < size; i++) 04724 { 04725 TopoDS_Shape* shape = shape_list.pop(); 04726 shape->Nullify(); 04727 delete shape; 04728 shape = NULL; 04729 } 04730 } 04731 if(!stat) 04732 return stat; 04733 return CUBIT_SUCCESS; 04734 } 04735 04736 //=============================================================================== 04737 // Function : check_operation 04738 // Member Type: PRIVATE 04739 // Description: check and update the from_shape according to type of the body. 04740 // Author : Jane Hu 04741 // Date : 06/08 04742 //=============================================================================== 04743 void OCCModifyEngine::check_operation(TopoDS_Shape& cut_shape, 04744 TopoDS_Shape*& from_shape, //output 04745 CubitBoolean is_volume, 04746 CubitBoolean& has_changed, //output 04747 BRepAlgoAPI_BooleanOperation* op, 04748 CubitBoolean keep_old) const 04749 { 04750 //compare to see if the from_shape has gotten cut. 04751 if(is_volume) 04752 { 04753 GProp_GProps myProps; 04754 BRepGProp::VolumeProperties(*from_shape, myProps); 04755 double orig_mass = myProps.Mass(); 04756 TopTools_IndexedMapOfShape M; 04757 TopExp::MapShapes(cut_shape, TopAbs_SOLID, M); 04758 double after_mass = 0.0; 04759 CubitBoolean no_volume = CUBIT_FALSE; 04760 if(M.Extent() > 0) 04761 { 04762 BRepGProp::VolumeProperties(cut_shape, myProps); 04763 after_mass = myProps.Mass(); 04764 } 04765 else 04766 no_volume = CUBIT_TRUE; 04767 04768 if(fabs(-after_mass + orig_mass) <= TOL) 04769 { 04770 has_changed= CUBIT_FALSE; //common is itself 04771 return; 04772 } 04773 04774 //got cut. Update the entities 04775 if(after_mass < TOL || no_volume) //no common section 04776 cut_shape.Nullify(); 04777 has_changed = CUBIT_TRUE; 04778 TopExp_Explorer Ex; 04779 int num_solid = 0; 04780 Ex.Init(*from_shape, TopAbs_SOLID); 04781 TopoDS_Solid old_solid; 04782 for(; Ex.More(); Ex.Next()) 04783 { 04784 num_solid ++; 04785 old_solid = TopoDS::Solid(Ex.Current()); 04786 } 04787 if(num_solid == 1) 04788 OCCLump::update_OCC_entity(old_solid , cut_shape, op); 04789 04790 else if(num_solid > 1) 04791 OCCBody::update_OCC_entity(*from_shape, cut_shape, op); 04792 } 04793 else 04794 { 04795 GProp_GProps myProps; 04796 BRepGProp::SurfaceProperties(*from_shape, myProps); 04797 double orig_mass = myProps.Mass(); 04798 BRepGProp::SurfaceProperties(cut_shape, myProps); 04799 double after_mass = myProps.Mass(); 04800 if(fabs(-after_mass + orig_mass) <= TOL) 04801 { 04802 has_changed= CUBIT_FALSE; //common is itself, or not cut 04803 return; 04804 } 04805 //got cut. Update the entities 04806 if(after_mass < TOL)//no common section 04807 cut_shape.Nullify(); 04808 has_changed = CUBIT_TRUE; 04809 if(from_shape->ShapeType() == TopAbs_SHELL) 04810 { 04811 TopoDS_Shell old_shell = TopoDS::Shell(*from_shape); 04812 OCCShell::update_OCC_entity(old_shell,cut_shape, op); 04813 } 04814 else 04815 { 04816 TopoDS_Face old_face = TopoDS::Face(*from_shape); 04817 OCCSurface::update_OCC_entity(old_face,cut_shape, op); 04818 } 04819 } 04820 // if(keep_old) - Must not be deleted, causes random failure on OSX 04821 // delete from_shape; 04822 from_shape = new TopoDS_Shape(cut_shape); 04823 } 04824 04825 //=============================================================================== 04826 // Function : chop 04827 // Member Type: PUBLIC 04828 // Description: chop boolean operation between OCC-based bodies 04829 // bodies has a size() = 2, a blank body and a tool body. 04830 // chops the blank with the tool, returing the body formed 04831 // by subtracting the tool from the blank, and the body formed 04832 // by intersecting the tool with the blank, simultaneously. 04833 // Author : Jane Hu 04834 // Date : 06/08 04835 //=============================================================================== 04836 CubitStatus OCCModifyEngine::chop(DLIList<BodySM*>& bodies, 04837 DLIList<BodySM*> &intersectBodies, 04838 DLIList<BodySM*> &outsideBodies, 04839 BodySM*& leftoversBody, 04840 bool keep_old , 04841 bool nonreg) const 04842 { 04843 //according to chop function, leftoverBody = 0; 04844 leftoversBody = 0; 04845 04846 //there's no effect of nonreg. keep_old mean if to keep the tool_body 04847 if(bodies.size() != 2) 04848 { 04849 PRINT_WARNING("Chop operation works only on two bodies. Nothing modified\n"); 04850 return CUBIT_FAILURE; 04851 } 04852 04853 //outsideBodies keeps the surface, curve ids if keep_old is false. 04854 BodySM* blank_body = bodies.get(); 04855 04856 //copy blank_body for intersect operation, because it will get changed. 04857 DLIList<BodySM*> tool_bodies, from_bodies; 04858 from_bodies.append(blank_body); 04859 BodySM* tool_body = bodies.step_and_get(); 04860 tool_bodies.append(tool_body); 04861 04862 CubitStatus stat = intersect(tool_body, from_bodies, 04863 intersectBodies, CUBIT_TRUE); 04864 04865 if(!stat) 04866 return CUBIT_FAILURE; 04867 04868 stat = subtract(tool_bodies, from_bodies, outsideBodies, 04869 CUBIT_FALSE, keep_old); 04870 04871 return stat; 04872 } 04873 04874 //=============================================================================== 04875 // Function : unite 04876 // Member Type: PUBLIC 04877 // Description: unite boolean operation between OCC-based bodies 04878 // Author : Jane Hu 04879 // Date : 06/08 04880 //=============================================================================== 04881 CubitStatus OCCModifyEngine::unite(DLIList<BodySM*> &bodies, 04882 DLIList<BodySM*> &newBodies, 04883 bool keep_old) const 04884 { 04885 if(bodies.size() < 2) 04886 { 04887 newBodies = bodies; 04888 return CUBIT_SUCCESS; 04889 } 04890 04891 //In order to distinguish bodies who are not intersecting each other to 04892 //avoid doing the boolean, check the minimum distance of the bodies first. 04893 DLIList<BodySM*> revised_bodies; 04894 DLIList<BodySM*> overlaped_bodies; 04895 DLIList<TopoDS_Shape*> overlap_shapes; 04896 DLIList<TopoDS_Shape*> shape_list; 04897 DLIList<TopoDS_Shape*> revised_shapes; 04898 DLIList<CubitBoolean> is_volume; 04899 CubitStatus stat = 04900 get_shape_list(bodies, shape_list, is_volume, keep_old); 04901 04902 if( !stat ) 04903 return CUBIT_FAILURE; 04904 04905 while(bodies.size() > 0) 04906 { 04907 TopoDS_Shape *shape1 = shape_list.pop(); 04908 BodySM* first_body = bodies.pop(); 04909 CubitBoolean intersect = false; 04910 shape_list.reset(); 04911 int size = shape_list.size(); 04912 04913 overlaped_bodies.clean_out(); 04914 overlap_shapes.clean_out(); 04915 for (int k = 0 ; k < size; k++) 04916 { 04917 TopoDS_Shape *shape2 = shape_list.get(); 04918 BodySM* sec_body = bodies.get(); 04919 BRepExtrema_DistShapeShape dist(*shape1, *shape2); 04920 //dist.Perform(); 04921 if(dist.IsDone() && dist.Value() < TOL) 04922 { 04923 overlaped_bodies.append(sec_body); 04924 overlap_shapes.append(shape2); 04925 bodies.change_to(NULL); 04926 shape_list.change_to(NULL); 04927 intersect = true; 04928 } 04929 bodies.step(); 04930 shape_list.step(); 04931 } 04932 bodies.remove_all_with_value(NULL); 04933 shape_list.remove_all_with_value(NULL); 04934 if (intersect != true) 04935 { 04936 revised_bodies.append(first_body); 04937 revised_shapes.append(shape1); 04938 } 04939 else 04940 { 04941 overlaped_bodies.append(first_body); 04942 overlap_shapes.append(shape1); 04943 04944 //find a non-sheet body to be the first shape 04945 TopoDS_Shape* first_shape; 04946 TopoDS_Shape* second_shape; 04947 CubitBoolean first_is_volume = false; 04948 for(int i = 0; i < overlap_shapes.size(); i++) 04949 { 04950 04951 first_shape = overlap_shapes.get(); 04952 if(first_shape->ShapeType() < TopAbs_SHELL) 04953 { 04954 first_is_volume = true; 04955 break; 04956 } 04957 overlap_shapes.step(); 04958 overlaped_bodies.step(); 04959 } 04960 overlap_shapes.remove(first_shape); 04961 BodySM* body1 = overlaped_bodies.remove(); 04962 BodySM* body2 = NULL; 04963 overlap_shapes.reset(); 04964 overlaped_bodies.reset(); 04965 for(int i = 0; i < overlap_shapes.size(); i++) 04966 { 04967 second_shape = overlap_shapes.get_and_step(); 04968 body2 = overlaped_bodies.get_and_step(); 04969 BRepAlgoAPI_Fuse fuser(*first_shape, *second_shape); 04970 TopoDS_Shape new_shape = fuser.Shape(); 04971 04972 CubitBoolean has_changed; 04973 TopTools_IndexedMapOfShape M1, M2, M_new; 04974 TopExp::MapShapes(*first_shape, TopAbs_SOLID, M1); 04975 TopExp::MapShapes(*second_shape, TopAbs_SOLID, M2); 04976 TopExp::MapShapes(new_shape, TopAbs_SOLID, M_new); 04977 if(M_new.Extent() == 1 && M1.Extent() > 1 && M2.Extent() == 1) 04978 { 04979 check_operation(new_shape,second_shape, is_volume[i], has_changed, &fuser, keep_old); 04980 check_operation(new_shape, first_shape, first_is_volume, has_changed, &fuser, keep_old); 04981 } 04982 04983 else if(M_new.Extent() == 1 && M1.Extent() > 1 && M2.Extent() > 1) 04984 //two compound bodies unite into one solid lump body 04985 { 04986 OCCQueryEngine::instance()->copy_attributes(*first_shape, new_shape); 04987 OCCQueryEngine::instance()->copy_attributes(*second_shape, new_shape); 04988 first_shape = new TopoDS_Shape(new_shape); 04989 OCCQueryEngine::instance()->delete_solid_model_entities(body1); 04990 OCCQueryEngine::instance()->delete_solid_model_entities(body2); 04991 } 04992 else 04993 { 04994 check_operation(new_shape, first_shape, first_is_volume, has_changed, &fuser, keep_old); 04995 04996 check_operation(new_shape,second_shape, is_volume[i], has_changed, &fuser, keep_old); 04997 } 04998 } 04999 //ok, we're done with all unites, construct new Body' 05000 DLIList<TopologyBridge*> tbs; 05001 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*first_shape); 05002 05003 BodySM* bodysm = CAST_TO(tbs.get(), BodySM); 05004 if (bodysm) 05005 { 05006 CAST_TO(bodysm, OCCBody)->get_TopoDS_Shape(first_shape); 05007 revised_bodies.append(bodysm); 05008 revised_shapes.append(first_shape); 05009 } 05010 } 05011 } 05012 05013 if (revised_bodies.size() > 1) 05014 { 05015 revised_shapes.clean_out(); 05016 is_volume.clean_out(); 05017 stat = 05018 get_shape_list(revised_bodies, revised_shapes, is_volume, true); 05019 05020 //simply make all bodies into a compound 05021 TopoDS_Compound Co ; 05022 BRep_Builder B; 05023 B.MakeCompound(Co); 05024 for(int i = 0; i < revised_shapes.size(); i++) 05025 B.Add(Co, *revised_shapes.get_and_step()); 05026 05027 BodySM* body = OCCQueryEngine::instance()->populate_topology_bridge(Co); 05028 if(body) 05029 newBodies.append(body); 05030 05031 //delete all other individial bodies 05032 if(keep_old == false) 05033 for(int i = 0; i < revised_bodies.size(); i++) 05034 OCCQueryEngine::instance()-> 05035 delete_solid_model_entities(revised_bodies.get_and_step()); 05036 revised_bodies.clean_out(); 05037 } 05038 05039 else if(revised_bodies.size() == 1) 05040 newBodies = revised_bodies; 05041 return CUBIT_SUCCESS; 05042 } 05043 05044 CubitStatus OCCModifyEngine::thicken( DLIList<BodySM*>& bodies, 05045 DLIList<BodySM*>& new_bodies, 05046 double depth, 05047 CubitBoolean both) const 05048 { 05049 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 05050 return CUBIT_FAILURE; 05051 } 05052 05053 //=============================================================================== 05054 // Function : hollow 05055 // Member Type: PUBLIC 05056 // Description: Hollow existing solid body by remove one or several surfaces 05057 // Can only take one body at a time. 05058 // depth > 0, thick body going outside bodies 05059 // depth < 0, thick body going inside bodies 05060 // Author : Jane Hu 05061 // Date : 06/08 05062 //=============================================================================== 05063 CubitStatus OCCModifyEngine::hollow( DLIList<BodySM*>& bodies, 05064 DLIList<Surface*>& surfs_to_remove, 05065 DLIList<BodySM*>& new_bodies, 05066 double depth) const 05067 { 05068 if(bodies.size() != 1 || surfs_to_remove.size() < 1) 05069 { 05070 PRINT_ERROR("Making thick solid in OCC will take one body and at least one surface at a time.\n"); 05071 return CUBIT_FAILURE; 05072 } 05073 05074 DLIList<TopoDS_Shape*> shape_list; 05075 DLIList<CubitBoolean> is_volume; 05076 CubitStatus stat = get_shape_list(bodies, shape_list, is_volume, CUBIT_FALSE); 05077 05078 if(!stat) 05079 return stat; 05080 05081 if(!is_volume.get())//sheet body 05082 { 05083 PRINT_ERROR("Making thick solid in OCC needs an initial solid body to hollow with.\n"); 05084 return CUBIT_FAILURE; 05085 } 05086 05087 //make sure the body to be hollowed has only one lump 05088 OCCBody* occ_body = CAST_TO(bodies.get(), OCCBody); 05089 DLIList<Lump*> lumps; 05090 DLIList<OCCSurface*> surfaces; 05091 DLIList<OCCShell*> shells; 05092 surfaces = occ_body->my_sheet_surfaces(); 05093 shells = occ_body->shells(); 05094 lumps = occ_body->lumps(); 05095 if(lumps.size()!=1 || surfaces.size() != 0 || shells.size() != 0) 05096 { 05097 PRINT_ERROR("bodies with more than one lump can't be hollowed to make a thick body.\n"); 05098 return CUBIT_FAILURE; 05099 } 05100 05101 //make sure surfs_to_remove are all in bodies 05102 TopTools_ListOfShape face_shapes; 05103 occ_body->get_all_surfaces(surfaces); 05104 for(int i = 0; i < surfs_to_remove.size(); i++) 05105 { 05106 OCCSurface* occ_surf = CAST_TO(surfs_to_remove.get(), OCCSurface); 05107 if(!occ_surf) 05108 continue; 05109 if(!surfaces.is_in_list(occ_surf)) 05110 continue; 05111 TopoDS_Face * face = occ_surf->get_TopoDS_Face(); 05112 face_shapes.Append(*face); 05113 } 05114 05115 if(face_shapes.IsEmpty()) 05116 { 05117 PRINT_ERROR("The surfaces provided should be from the body to be hollowed.\n"); 05118 return CUBIT_FAILURE; 05119 } 05120 05121 double dTOL = 1.e-3; //hard coded for now, can be changed by application 05122 TopoDS_Shape* solid = shape_list.get(); 05123 BRepOffsetAPI_MakeThickSolid hollower(*solid, face_shapes, depth, dTOL, 05124 BRepOffset_Skin, Standard_False, 05125 Standard_False, GeomAbs_Intersection); 05126 TopoDS_Shape new_shape = hollower.Shape(); 05127 if(solid->ShapeType() == TopAbs_SOLID) 05128 { 05129 TopoDS_Solid old_solid = TopoDS::Solid(*solid); 05130 OCCLump::update_OCC_entity(old_solid , new_shape, &hollower); 05131 } 05132 else if(solid->ShapeType() == TopAbs_COMPOUND) 05133 OCCBody::update_OCC_entity(*solid, new_shape, &hollower); 05134 05135 //ok, we're done with all hollowing, construct new Body' 05136 DLIList<TopologyBridge*> tbs; 05137 tbs += OCCQueryEngine::instance()->populate_topology_bridge(new_shape); 05138 05139 for (int i = 0; i< tbs.size(); i++) 05140 { 05141 BodySM* bodysm = CAST_TO(tbs.get_and_step(), BodySM); 05142 if (bodysm) 05143 new_bodies.append(bodysm); 05144 } 05145 05146 return CUBIT_SUCCESS; 05147 } 05148 05149 05150 //=============================================================================== 05151 // Function : flip_normals 05152 // Member Type: PUBLIC 05153 // Description: 05154 // Author : Jane Hu 05155 // Date : 06/08 05156 //=============================================================================== 05157 CubitStatus OCCModifyEngine :: flip_normals( DLIList<Surface*>& face_list ) const 05158 { 05159 return CUBIT_FAILURE; 05160 /* 05161 DLIList<Surface*> surface_list; 05162 while (face_list.size()) 05163 { 05164 OCCSurface* occ_surface = CAST_TO(face_list.pop(), OCCSurface); 05165 OCCShell* occ_shell = occ_surface->my_shell(); 05166 DLIList<OCCSurface*> surfaces; 05167 surfaces.append(occ_surface); 05168 if(occ_shell) //find all surfaces in face_list that belong to this shell 05169 { 05170 int size = face_list.size(); 05171 for ( int i = 0; i < size; i++) 05172 { 05173 occ_surface = CAST_TO(face_list.get(), OCCSurface); 05174 if(occ_shell == occ_surface->my_shell()) 05175 surfaces.append(CAST_TO(face_list.remove(),OCCSurface)); 05176 else 05177 face_list.step(); 05178 } 05179 05180 if (!occ_shell->is_sheet()) 05181 { 05182 DLIList<OCCSurface*> memberSurfs = occ_shell->getMemberSurfaces(); 05183 for (int i = 0; i < memberSurfs.size(); ++i) 05184 { 05185 occ_surface = memberSurfs.get_and_step(); 05186 if(surfaces.is_in_list(occ_surface)) 05187 { 05188 // would need to implement flipping the normal here 05189 surface_list.append(occ_surface); 05190 } 05191 } 05192 } 05193 } 05194 if(!occ_shell || occ_shell->is_sheet()) //sheet body 05195 { 05196 // would need to implement flipping the normal here 05197 surface_list.append(occ_surface); 05198 PRINT_INFO( "Modified volume\n" ); 05199 } 05200 } 05201 face_list = surface_list; 05202 return CUBIT_SUCCESS; 05203 */ 05204 } 05205 05206 05207 //=============================================================================== 05208 // Function : sweep_translational 05209 // Member Type: PUBLIC 05210 // Description: 05211 // Author : Jane Hu 05212 // Date : 09/08 05213 //=============================================================================== 05214 CubitStatus OCCModifyEngine::sweep_translational( 05215 DLIList<GeometryEntity*>& ref_ent_list, 05216 DLIList<BodySM*>& result_body_list, 05217 const CubitVector& sweep_vector, 05218 double draft_angle, //in Radius 05219 int draft_type, //RightCorner=1 or RoundCorner =2 05220 bool switchside,//not used, shell and surfaces are one sided, not like 05221 bool rigid, //not used here, in , it means whether the end surface is 05222 // parallel to the starting surface, or perpendicular to the path 05223 bool anchor_entity, //not used in OCC 05224 bool keep_old) const 05225 { 05226 //in OCC, there's no sweep surface with draft option, this can be done by 05227 //creating draft shell then make solid to achieve. 05228 //while if draft_angle is 0, directly use sweep functions. 05229 05230 gp_Dir adir(sweep_vector.x(), sweep_vector.y(), sweep_vector.z()); 05231 gp_Vec aVec(sweep_vector.x(), sweep_vector.y(), sweep_vector.z()); 05232 05233 for (int i = ref_ent_list.size(); i > 0; i--) 05234 { 05235 GeometryEntity *ref_ent = ref_ent_list.get_and_step(); 05236 //Make copy of the surface for later to build solid. 05237 OCCSurface* surface = CAST_TO(ref_ent, OCCSurface); 05238 TopoDS_Shape toposhape ; 05239 if(surface != NULL) 05240 { 05241 CubitStatus stat = get_sweepable_toposhape(surface, &sweep_vector, toposhape); 05242 if(!stat) 05243 continue; 05244 } 05245 OCCCurve* curve = CAST_TO(ref_ent, OCCCurve); 05246 if(curve != NULL) 05247 { 05248 CubitStatus stat = get_sweepable_toposhape(curve, toposhape); 05249 if(!stat) 05250 continue; 05251 } 05252 05253 DLIList<TopologyBridge*> tbs; 05254 //create the draft or the sweep 05255 BodySM* bodysm = NULL; 05256 if( draft_angle == 0.) 05257 { 05258 BRepSweep_Prism swept(toposhape, aVec); 05259 TopoDS_Shape new_shape = swept.Shape(); 05260 05261 tbs += OCCQueryEngine::instance()->populate_topology_bridge(new_shape); 05262 assert(tbs.size() == 1); 05263 05264 bodysm = CAST_TO(tbs.get(), BodySM); 05265 } 05266 05267 else 05268 { 05269 BRepOffsetAPI_MakeDraft draft(toposhape, adir, draft_angle); 05270 BRepBuilderAPI_TransitionMode Cornertype; 05271 if(draft_type == 1) 05272 Cornertype = BRepBuilderAPI_RightCorner; 05273 else 05274 Cornertype = BRepBuilderAPI_RoundCorner; 05275 05276 draft.SetOptions(Cornertype); 05277 draft.Perform(sweep_vector.length()); 05278 TopoDS_Shape new_shape = draft.Shape(); 05279 05280 tbs += OCCQueryEngine::instance()->populate_topology_bridge(new_shape); 05281 05282 assert(tbs.size() == 1); 05283 05284 bodysm = CAST_TO(tbs.get(), BodySM); 05285 if(bodysm && surface != NULL) //only gets swept side and original surfaces 05286 { 05287 //get surfaces from the shell body and create a top surface to 05288 //make a swept solid. 05289 DLIList<OCCShell*> shells = CAST_TO(bodysm, OCCBody)->shells(); 05290 if(shells.size() == 0) 05291 { 05292 PRINT_WARNING("Sweep surface failed inside OCC engine.\n"); 05293 return CUBIT_FAILURE; 05294 } 05295 assert(shells.size() == 1); 05296 DLIList<OCCSurface*> memberSurfaces = 05297 shells.get()->getMemberSurfaces(); 05298 DLIList<Surface*> surface_list; 05299 for (int i = 0; i < memberSurfaces.size(); ++i) 05300 surface_list.append(memberSurfaces.get_and_step()); 05301 05302 //create the top surface from edges. 05303 DLIList<OCCCoEdge*> coedges; 05304 for(int i = 0; i < surface_list.size(); i++) 05305 CAST_TO(surface_list.get_and_step(), OCCSurface)->get_coedges(coedges); 05306 for(int i = 0; i < coedges.size(); i++) 05307 { 05308 OCCCoEdge* coedge = coedges[i]; 05309 if(coedge == NULL) 05310 continue; 05311 for(int j = i+1; j < coedges.size(); j++) 05312 { 05313 OCCCoEdge* temp_coedge = coedges[j]; 05314 if(temp_coedge == NULL) 05315 continue; 05316 if(coedge->curve() == temp_coedge->curve()) //Since the shell 05317 // is open, the sense of curve can be either the same or opposite. 05318 { 05319 coedges.move_to(coedge); 05320 coedges.change_to((OCCCoEdge*)NULL); 05321 coedges.move_to(temp_coedge); 05322 coedges.change_to((OCCCoEdge*)NULL); 05323 } 05324 } 05325 } 05326 coedges.remove_all_with_value(NULL); 05327 assert(coedges.size() > 0); 05328 DLIList<Curve*> curves; 05329 for(int i = 0; i < coedges.size(); i++) 05330 curves.append(coedges.get_and_step()->curve()); 05331 05332 Surface* surf = make_Surface(PLANE_SURFACE_TYPE, curves); 05333 if(!surf) 05334 surf = make_Surface(BEST_FIT_SURFACE_TYPE, curves); 05335 if(!surf) 05336 { 05337 PRINT_ERROR("Can't calculate for the top surface.\n"); 05338 continue; 05339 } 05340 surface_list.append(surf); 05341 DLIList<BodySM*> bodies; 05342 create_solid_bodies_from_surfs(surface_list, bodies); 05343 05344 if(bodies.size() == 1) 05345 bodysm = bodies.get(); 05346 else 05347 { 05348 PRINT_WARNING("Sweep surface failed in creating solid.\n"); 05349 return CUBIT_FAILURE; 05350 } 05351 } 05352 } 05353 if(bodysm && !keep_old && surface != NULL) 05354 { 05355 //have to unite the new geometry with the old one. 05356 DLIList<BodySM*> bodies; 05357 DLIList<OCCBody*> occ_bodies; 05358 surface->get_bodies(occ_bodies); 05359 if(occ_bodies.size() == 1) 05360 { 05361 OCCBody* old_body = occ_bodies.get(); 05362 //delete sheet body if surface is standalong. 05363 if (old_body->is_sheet_body()) 05364 { 05365 OCCQueryEngine::instance()->delete_solid_model_entities(old_body); 05366 result_body_list.append(bodysm); 05367 } 05368 else 05369 { 05370 bodies.append(CAST_TO(old_body, BodySM)); 05371 bodies.append(bodysm); 05372 DLIList<BodySM*> newBodies; 05373 bool keep_old = CUBIT_FALSE; 05374 CubitStatus stat = unite(bodies, newBodies, keep_old); 05375 if(stat) 05376 result_body_list.append(newBodies.get()); 05377 } 05378 } 05379 } 05380 else if (bodysm) 05381 result_body_list.append(bodysm); 05382 } 05383 return CUBIT_SUCCESS; 05384 } 05385 05386 CubitStatus OCCModifyEngine::get_sweepable_toposhape(OCCCurve*& curve, 05387 TopoDS_Shape& toposhape)const 05388 { 05389 TopoDS_Edge *edge = curve->get_TopoDS_Edge( ); 05390 BRepBuilderAPI_Copy api_copy(*edge); 05391 toposhape = api_copy.ModifiedShape(*edge); 05392 TopoDS_Edge new_edge = TopoDS::Edge(toposhape); 05393 toposhape = BRepBuilderAPI_MakeWire(new_edge); 05394 05395 return CUBIT_SUCCESS; 05396 } 05397 05398 CubitStatus OCCModifyEngine::get_sweepable_toposhape(OCCSurface*& surface, 05399 const CubitVector* sweep_v_p, 05400 TopoDS_Shape& toposhape)const 05401 { 05402 GeometryEntity* ref_ent = surface; 05403 05404 if(surface != NULL) 05405 { 05406 //Make copy of the surface's topo_shape. 05407 TopoDS_Shape* toposhape_prt = 05408 OCCQueryEngine::instance()->get_TopoDS_Shape_of_entity(ref_ent); 05409 05410 if(!toposhape_prt) 05411 { 05412 PRINT_WARNING("GeometryEntity without TopoDS_Shape found.\n"); 05413 return CUBIT_FAILURE; 05414 } 05415 05416 BRepBuilderAPI_Copy api_copy(*toposhape_prt); 05417 toposhape = api_copy.ModifiedShape(*toposhape_prt); 05418 if(sweep_v_p) 05419 { 05420 CubitVector center = surface->center_point(); 05421 CubitVector normal; 05422 surface->closest_point(center,NULL,&normal); 05423 CubitVector sweep_vector = *sweep_v_p; 05424 // TODO: Determine where there might be need to have the normal vector 05425 // in the opposite direction if normal % sweep_vector > 0 05426 if (normal % sweep_vector == 0) 05427 { 05428 PRINT_ERROR("Sweeping direction should not be on the surface.\n"); 05429 return CUBIT_FAILURE; 05430 } 05431 } 05432 } 05433 return CUBIT_SUCCESS; 05434 } 05435 //=============================================================================== 05436 // Member Type: PUBLIC 05437 // Description: 05438 // Author : Jane Hu 05439 // Date : 10/08 05440 //=============================================================================== 05441 CubitStatus OCCModifyEngine::sweep_perpendicular( 05442 DLIList<GeometryEntity*>& ref_ent_list, 05443 DLIList<BodySM*>& result_body_list, 05444 double distance, 05445 double draft_angle, 05446 int draft_type, 05447 bool switchside, //has no effect 05448 bool rigid, //has no effect 05449 bool anchor_entity, //not used in OCC 05450 bool keep_old) const 05451 { 05452 //find the vector perpendicular to the ref_ent normal, and sweep_translate 05453 //the 'distance' along this vector 05454 DLIList<GeometryEntity*> edge_list; 05455 CubitVector vec; 05456 for(int i = 0; i < ref_ent_list.size(); i++) 05457 { 05458 GeometryEntity *ref_ent = ref_ent_list.get_and_step(); 05459 Surface *face = CAST_TO(ref_ent, Surface); 05460 Curve* edge = CAST_TO(ref_ent, Curve); 05461 DLIList<GeometryEntity*> face_list; 05462 if(face != NULL) 05463 { 05464 OCCSurface* occ_face = CAST_TO(face, OCCSurface); 05465 CubitVector center = occ_face->center_point(); 05466 CubitVector closest_p, unit_normal; 05467 CubitStatus stat = 05468 occ_face->closest_point(center, &closest_p, &unit_normal); 05469 if(stat) 05470 { 05471 vec = distance * unit_normal; 05472 face_list.append(ref_ent); 05473 stat = sweep_translational(face_list, result_body_list, vec, 05474 draft_angle, draft_type, switchside, 05475 rigid, anchor_entity, keep_old); 05476 } 05477 } 05478 else if (edge != NULL) 05479 { 05480 edge_list.append(ref_ent); 05481 } 05482 } 05483 if(edge_list.size()) 05484 PRINT_ERROR("Curves cannot be swept perpendicularly, please use the vector sweep.\n"); 05485 05486 return CUBIT_SUCCESS; 05487 } 05488 05489 //=============================================================================== 05490 // Function : sweep_rotational 05491 // Member Type: PUBLIC 05492 // Description: 05493 // Author : Jane Hu 05494 // Date : 10/08 05495 //=============================================================================== 05496 CubitStatus OCCModifyEngine:: sweep_rotational( 05497 DLIList<GeometryEntity*>& ref_ent_list, 05498 DLIList<BodySM*>& result_body_list, 05499 const CubitVector& point, 05500 const CubitVector& direction, 05501 double angle, //in radians 05502 int steps, //not used 05503 double draft_angle, //not used 05504 int draft_type, //not used 05505 bool switchside, //not used 05506 bool make_solid, 05507 bool rigid, //not used 05508 bool anchor_entity, //not used 05509 bool keep_old ) const 05510 { 05511 gp_Dir adir(direction.x(), direction.y(), direction.z()); 05512 gp_Pnt pt = gp_Pnt( point.x(), point.y(), point.z()); 05513 gp_Ax1 axis = gp_Ax1(pt, adir); 05514 05515 gp_Lin line = gp_Lin(axis); 05516 TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(line); 05517 OCCCurve* acurve = CAST_TO(OCCQueryEngine::instance()->populate_topology_bridge(edge, CUBIT_TRUE), OCCCurve); 05518 assert(acurve); 05519 05520 CubitVector start; 05521 CubitVector end; 05522 05523 for (int i = ref_ent_list.size(); i > 0; i--) 05524 { 05525 GeometryEntity *ref_ent = ref_ent_list.get_and_step(); 05526 //Make copy of the surface or curve for later to build solid. 05527 OCCSurface* surface = CAST_TO(ref_ent, OCCSurface); 05528 OCCCurve* curve = CAST_TO(ref_ent, OCCCurve); 05529 TopoDS_Shape toposhape ; 05530 if(surface != NULL) 05531 { 05532 CubitStatus stat = get_sweepable_toposhape(surface, (CubitVector*)NULL, toposhape); 05533 if(!stat) 05534 continue; 05535 //only non-intersecting of surface and axis can be swept. 05536 DLIList<CubitVector> intersect_pts; 05537 OCCQueryEngine::instance()->get_intersections(acurve, surface, 05538 intersect_pts, CUBIT_TRUE); 05539 if(intersect_pts.size() > 0) 05540 { 05541 PRINT_ERROR("Only surfaces with no intersection point with the axis can be revolve-swept.\n"); 05542 continue; 05543 } 05544 } 05545 else if(curve != NULL) 05546 { 05547 CubitStatus stat = get_sweepable_toposhape(curve, toposhape); 05548 if(!stat) 05549 continue; 05550 //closed curve can't intersect with the axis, while open curve can only 05551 //intersect the axis at the end points. 05552 //only curve not intersecting with axis in curve's middle locations 05553 //can be revolved 05554 DLIList<CubitVector> intersect_pts; 05555 OCCQueryEngine::instance()->get_intersections(curve, acurve, 05556 intersect_pts, CUBIT_TRUE, CUBIT_TRUE); 05557 if(!toposhape.Closed()) 05558 { 05559 //get start and end points 05560 DLIList<OCCPoint*> point_list; 05561 curve->get_points(point_list); 05562 assert(2 == point_list.size()); 05563 GeometryType type = curve->geometry_type(); 05564 start = point_list.get_and_step()->coordinates(); 05565 end = point_list.get()->coordinates(); 05566 CubitBoolean start_int = CUBIT_FALSE; 05567 CubitBoolean end_int = CUBIT_FALSE; 05568 if(intersect_pts.size() > 0) 05569 { 05570 CubitBoolean non_int = CUBIT_FALSE; 05571 for(int i = 0; i < intersect_pts.size(); i++) 05572 { 05573 CubitVector &prt = intersect_pts.get_and_step(); 05574 if(prt.distance_between(start) > TOL && 05575 prt.distance_between(end) > TOL) 05576 { 05577 non_int = CUBIT_TRUE; 05578 PRINT_ERROR("Only curves with no intersection point with the axis can be revolve-swept.\n"); 05579 break; 05580 } 05581 else if(prt.distance_between(start) <= TOL) 05582 start_int = CUBIT_TRUE; 05583 else if(prt.distance_between(end) <= TOL) 05584 end_int = CUBIT_TRUE; 05585 } 05586 if(non_int) 05587 continue; 05588 if(start_int && end_int && type == STRAIGHT_CURVE_TYPE) 05589 { 05590 PRINT_ERROR("Sweep along curve itself is not allowed.\n"); 05591 continue; 05592 } 05593 } 05594 } 05595 else 05596 { 05597 if(intersect_pts.size() > 0) 05598 { 05599 PRINT_ERROR("Only curves with no intersection point with the axis can be revolve-swept.\n"); 05600 continue; 05601 } 05602 } 05603 } 05604 else 05605 { 05606 PRINT_ERROR("Only surface or curve can be revolve-swept.\n"); 05607 continue; 05608 } 05609 TopoDS_Shape new_shape; 05610 DLIList<TopologyBridge*> tbs; 05611 if(make_solid && curve != NULL ) 05612 //giving an open wire and want a solid 05613 { 05614 if(!toposhape.Closed()) 05615 { 05616 //project the start and end points onto the axis 05617 CubitBoolean start_closed = CUBIT_FALSE; 05618 CubitBoolean end_closed = CUBIT_FALSE; 05619 if(acurve->point_containment(start) != CUBIT_PNT_OFF) 05620 start_closed = CUBIT_TRUE; 05621 if(acurve->point_containment(end) != CUBIT_PNT_OFF) 05622 end_closed = CUBIT_TRUE; 05623 CubitVector start_proj, end_proj; 05624 TopoDS_Edge edge1, edge2; 05625 BRepBuilderAPI_MakeWire m_wire; 05626 if(!start_closed) 05627 { 05628 acurve->closest_point(start, start_proj); 05629 gp_Pnt pt1 = gp_Pnt( start.x(), start.y(), start.z()); 05630 gp_Pnt pt2 = gp_Pnt( start_proj.x(), start_proj.y(), start_proj.z()); 05631 edge1 = BRepBuilderAPI_MakeEdge(pt1, pt2); 05632 m_wire.Add(edge1); 05633 m_wire.Add(TopoDS::Wire(toposhape)); 05634 } 05635 else 05636 { 05637 m_wire.Add(TopoDS::Wire(toposhape)); 05638 start_proj = start; 05639 } 05640 05641 if(!end_closed) 05642 { 05643 acurve->closest_point(end,end_proj); 05644 gp_Pnt pt1 = gp_Pnt( end.x(), end.y(), end.z()); 05645 gp_Pnt pt2 = gp_Pnt( end_proj.x(), end_proj.y(), end_proj.z()); 05646 edge2 = BRepBuilderAPI_MakeEdge(pt1, pt2); 05647 m_wire.Add(edge2); 05648 } 05649 05650 else 05651 end_proj = end; 05652 05653 gp_Pnt pt1 = gp_Pnt( end_proj.x(), end_proj.y(), end_proj.z()); 05654 gp_Pnt pt2 = gp_Pnt( start_proj.x(), start_proj.y(), start_proj.z()); 05655 TopoDS_Edge edge3 = BRepBuilderAPI_MakeEdge(pt2, pt1); 05656 m_wire.Add(edge3); 05657 05658 TopoDS_Wire wire = m_wire.Wire(); 05659 toposhape = BRepBuilderAPI_MakeFace(wire); 05660 } 05661 else //closed 05662 { 05663 TopoDS_Wire wire = TopoDS::Wire(toposhape); 05664 toposhape = BRepBuilderAPI_MakeFace(wire); 05665 } 05666 } 05667 BRepSweep_Revol revol(toposhape, axis, angle); 05668 new_shape = revol.Shape(); 05669 05670 tbs += OCCQueryEngine::instance()->populate_topology_bridge(new_shape); 05671 assert(tbs.size() == 1); 05672 05673 BodySM* bodysm = CAST_TO(tbs.get(), BodySM); 05674 05675 if(bodysm && !keep_old && surface != NULL) 05676 { 05677 //have to unite the new geometry with the old one. 05678 DLIList<BodySM*> bodies; 05679 DLIList<OCCBody*> occ_bodies; 05680 surface->get_bodies(occ_bodies); 05681 if(occ_bodies.size() == 1) 05682 { 05683 OCCBody* old_body = occ_bodies.get(); 05684 //delete sheet body if surface is standalong. 05685 if (old_body->is_sheet_body()) 05686 { 05687 OCCQueryEngine::instance()->delete_solid_model_entities(old_body); 05688 result_body_list.append(bodysm); 05689 } 05690 else 05691 { 05692 bodies.append(CAST_TO(old_body, BodySM)); 05693 bodies.append(bodysm); 05694 DLIList<BodySM*> newBodies; 05695 CubitStatus stat = unite(bodies, newBodies, CUBIT_FALSE); 05696 if(stat) 05697 result_body_list.append(newBodies.get()); 05698 } 05699 } 05700 } 05701 else if (bodysm) 05702 result_body_list.append(bodysm); 05703 continue; 05704 } 05705 OCCQueryEngine::instance()->delete_solid_model_entities(acurve); 05706 if(result_body_list.size()>0) 05707 return CUBIT_SUCCESS; 05708 else 05709 return CUBIT_FAILURE; 05710 } 05711 05712 //=============================================================================== 05713 // Function : sweep_along_curve 05714 // Member Type: PUBLIC 05715 // Description: The ref_edge_list must provide a list of curves which are 05716 // connected, and making G1 continuous wire. 05717 // Author : Jane Hu 05718 // Date : 10/08 05719 //=============================================================================== 05720 CubitStatus OCCModifyEngine::sweep_along_curve( 05721 DLIList<GeometryEntity*>& ref_ent_list, 05722 DLIList<BodySM*>& result_body_list, 05723 DLIList<Curve*>& ref_edge_list, 05724 double draft_angle, //only used for straight curve case 05725 int draft_type, //only used for straight curve case 05726 bool rigid, //not used 05727 bool anchor_entity, //not used 05728 bool keep_old) const 05729 { 05730 //make wire out of ref_edge_list 05731 BRepBuilderAPI_MakeWire awire; 05732 TopTools_ListOfShape L; 05733 OCCCurve* occ_curve = NULL; 05734 GeometryType type = UNDEFINED_CURVE_TYPE; 05735 int num_curve = 0; 05736 for(int i = 0; i < ref_edge_list.size(); i++) 05737 { 05738 Curve* curve = ref_edge_list.get_and_step(); 05739 occ_curve = CAST_TO(curve, OCCCurve); 05740 if(!occ_curve) 05741 continue; 05742 TopoDS_Edge* topoedge = occ_curve->get_TopoDS_Edge( ); 05743 BRepBuilderAPI_Copy api_copy(*topoedge); 05744 TopoDS_Shape newShape = api_copy.ModifiedShape(*topoedge); 05745 L.Append(newShape); 05746 type = occ_curve->geometry_type(); 05747 num_curve++; 05748 } 05749 if(L.IsEmpty()) 05750 { 05751 PRINT_ERROR("There's no valid sweeping path.\n"); 05752 return CUBIT_FAILURE; 05753 } 05754 05755 if(num_curve == 1 && type == STRAIGHT_CURVE_TYPE && draft_angle != 0.0) 05756 { 05757 DLIList<OCCPoint*> point_list; 05758 occ_curve->get_points(point_list); 05759 CubitVector v1 = point_list.get_and_step()->coordinates(); 05760 CubitVector v2 = point_list.get()->coordinates(); 05761 CubitVector sweep_vector = v2-v1; 05762 return sweep_translational(ref_ent_list,result_body_list,sweep_vector, 05763 draft_angle, draft_type, CUBIT_FALSE, 05764 rigid, anchor_entity, keep_old); 05765 } 05766 awire.Add(L); 05767 TopoDS_Wire wire; 05768 wire = awire.Wire(); 05769 05770 BRepTools_WireExplorer it(wire); 05771 int num_edges = 0; 05772 for(; it.More(); it.Next()) 05773 num_edges++; 05774 05775 BRepLib_FuseEdges fuser(wire); 05776 fuser.SetConcatBSpl(); 05777 fuser.Perform(); 05778 TopoDS_Shape spline = fuser.Shape(); 05779 wire = TopoDS::Wire(spline); 05780 05781 DLIList<TopologyBridge*> tbs; 05782 for (int i = ref_ent_list.size(); i > 0; i--) 05783 { 05784 GeometryEntity *ref_ent = ref_ent_list.get_and_step(); 05785 //Make copy of the surface or curve for later to build solid. 05786 OCCSurface* surface = CAST_TO(ref_ent, OCCSurface); 05787 OCCCurve* curve = CAST_TO(ref_ent, OCCCurve); 05788 TopoDS_Shape toposhape ; 05789 if(surface != NULL) 05790 { 05791 CubitStatus stat = get_sweepable_toposhape(surface, (CubitVector*)NULL, toposhape); 05792 if(!stat) 05793 continue; 05794 } 05795 else if(curve != NULL) 05796 { 05797 CubitStatus stat = get_sweepable_toposhape(curve, toposhape); 05798 if(!stat) 05799 continue; 05800 } 05801 05802 //sweep along the wire 05803 BRepOffsetAPI_MakePipe maker(wire, toposhape); 05804 if(!maker.IsDone()) 05805 { 05806 PRINT_ERROR("Can't sweep along the provided curve(s).\n"); 05807 continue; 05808 } 05809 TopoDS_Shape newShape = maker.Shape(); 05810 05811 tbs += OCCQueryEngine::instance()->populate_topology_bridge(newShape); 05812 assert(tbs.size() == 1); 05813 05814 BodySM* bodysm = CAST_TO(tbs.get(), BodySM); 05815 05816 if(bodysm && !keep_old && surface != NULL) 05817 { 05818 //have to unite the new geometry with the old one. 05819 DLIList<BodySM*> bodies; 05820 DLIList<OCCBody*> occ_bodies; 05821 surface->get_bodies(occ_bodies); 05822 if(occ_bodies.size() == 1) 05823 { 05824 OCCBody* old_body = occ_bodies.get(); 05825 //delete sheet body if surface is standalong. 05826 if (old_body->is_sheet_body()) 05827 { 05828 OCCQueryEngine::instance()->delete_solid_model_entities(old_body); 05829 result_body_list.append(bodysm); 05830 } 05831 else 05832 { 05833 bodies.append(CAST_TO(old_body, BodySM)); 05834 bodies.append(bodysm); 05835 DLIList<BodySM*> newBodies; 05836 CubitStatus stat = unite(bodies, newBodies, CUBIT_FALSE); 05837 if(stat) 05838 result_body_list.append(newBodies.get()); 05839 } 05840 } 05841 } 05842 else if (bodysm) 05843 result_body_list.append(bodysm); 05844 } 05845 return CUBIT_SUCCESS; 05846 } 05847 05848 CubitStatus OCCModifyEngine::sweep_to_body( 05849 DLIList<Curve*> curve_list, 05850 BodySM *target_body, 05851 CubitVector sweep_vector, 05852 DLIList<BodySM*> &new_bodies, 05853 bool unite) const 05854 { 05855 TopoDS_Shape *stop_shape = NULL; 05856 OCCBody* occ_body = CAST_TO(target_body, OCCBody); 05857 occ_body->get_TopoDS_Shape(stop_shape); 05858 05859 gp_Dir adir(sweep_vector.x(), sweep_vector.y(), sweep_vector.z()); 05860 05861 DLIList<BodySM*> swept_bodies; 05862 for(int i = 0; i < curve_list.size(); i++) 05863 { 05864 OCCCurve* curve = CAST_TO(curve_list.get_and_step(), OCCCurve); 05865 TopoDS_Shape toposhape ; 05866 CubitStatus stat = get_sweepable_toposhape(curve, toposhape); 05867 if(!stat) 05868 continue; 05869 BRepOffsetAPI_MakeDraft draft(toposhape, adir, 0.0); 05870 draft.Perform(*stop_shape); 05871 TopoDS_Shape new_shape = draft.Shape(); 05872 DLIList<TopologyBridge*> tbs; 05873 tbs = OCCQueryEngine::instance()->populate_topology_bridge(new_shape); 05874 assert(tbs.size() == 1); 05875 BodySM* bodysm = CAST_TO(tbs.get(), BodySM); 05876 if (bodysm) 05877 swept_bodies.append(bodysm); 05878 } 05879 if(unite) 05880 return this->unite(swept_bodies, new_bodies, CUBIT_FALSE); 05881 new_bodies += swept_bodies; 05882 return CUBIT_SUCCESS; 05883 } 05884 05885 CubitStatus OCCModifyEngine::sweep_to_body( 05886 Surface *source_surface, 05887 BodySM *target_body, 05888 CubitVector sweep_vector, 05889 DLIList<BodySM*> &new_bodies ) const 05890 { 05891 TopoDS_Shape *stop_shape = NULL; 05892 OCCBody* occ_body = CAST_TO(target_body, OCCBody); 05893 occ_body->get_TopoDS_Shape(stop_shape); 05894 05895 gp_Dir adir(sweep_vector.x(), sweep_vector.y(), sweep_vector.z()); 05896 05897 DLIList<BodySM*> swept_bodies; 05898 OCCSurface* surf = CAST_TO(source_surface, OCCSurface); 05899 TopoDS_Shape toposhape ; 05900 CubitStatus stat = get_sweepable_toposhape(surf, &sweep_vector, toposhape); 05901 if(!stat) 05902 return CUBIT_FAILURE; 05903 BRepOffsetAPI_MakeDraft draft(toposhape, adir, 0.0); 05904 draft.Perform(*stop_shape); 05905 TopoDS_Shape new_shape = draft.Shape(); 05906 DLIList<TopologyBridge*> tbs; 05907 tbs = OCCQueryEngine::instance()->populate_topology_bridge(new_shape); 05908 assert(tbs.size() == 1); 05909 BodySM* bodysm = CAST_TO(tbs.get(), BodySM); 05910 //get surfaces from the shell body and create a top surface to 05911 //make a swept solid. 05912 DLIList<OCCShell*> shells = CAST_TO(bodysm, OCCBody)->shells(); 05913 if(shells.size() == 0) 05914 { 05915 PRINT_WARNING("Sweep surface failed inside OCC engine.\n"); 05916 return CUBIT_FAILURE; 05917 } 05918 assert(shells.size() == 1); 05919 DLIList<OCCSurface*> memberSurfaces = shells.get()->getMemberSurfaces(); 05920 DLIList<Surface*> surface_list; 05921 for (int i = 0; i < memberSurfaces.size(); ++i) 05922 surface_list.append(memberSurfaces.get_and_step()); 05923 05924 //create the top surface from edges. 05925 DLIList<OCCCoEdge*> coedges; 05926 for(int i = 0; i < surface_list.size(); i++) 05927 CAST_TO(surface_list.get_and_step(), OCCSurface)->get_coedges(coedges); 05928 for(int i = 0; i < coedges.size(); i++) 05929 { 05930 OCCCoEdge* coedge = coedges[i]; 05931 if(coedge == NULL) 05932 continue; 05933 for(int j = i+1; j < coedges.size(); j++) 05934 { 05935 OCCCoEdge* temp_coedge = coedges[j]; 05936 if(temp_coedge == NULL) 05937 continue; 05938 if(coedge->curve() == temp_coedge->curve()) //Since the shell 05939 // is open, the sense of curve can be either the same or opposite. 05940 { 05941 coedges.move_to(coedge); 05942 coedges.change_to((OCCCoEdge*)NULL); 05943 coedges.move_to(temp_coedge); 05944 coedges.change_to((OCCCoEdge*)NULL); 05945 } 05946 } 05947 } 05948 coedges.remove_all_with_value(NULL); 05949 assert(coedges.size() > 0); 05950 DLIList<Curve*> curves; 05951 for(int i = 0; i < coedges.size(); i++) 05952 curves.append(coedges.get_and_step()->curve()); 05953 05954 Surface* surface = make_Surface(PLANE_SURFACE_TYPE, curves); 05955 if(!surface) 05956 surface = make_Surface(BEST_FIT_SURFACE_TYPE, curves); 05957 if(!surface) 05958 { 05959 PRINT_ERROR("Can't calculate for the top surface.\n"); 05960 return CUBIT_FAILURE; 05961 } 05962 surface_list.append(surface); 05963 DLIList<BodySM*> bodies; 05964 create_solid_bodies_from_surfs(surface_list, bodies); 05965 05966 if(bodies.size() == 1) 05967 bodysm = bodies.get(); 05968 else 05969 { 05970 PRINT_WARNING("Sweep surface failed in creating solid.\n"); 05971 return CUBIT_FAILURE; 05972 } 05973 if (bodysm) 05974 new_bodies.append(bodysm); 05975 return CUBIT_SUCCESS; 05976 } 05977 05978 //HEADER- Webcut-related functions 05979 05980 //=============================================================================== 05981 // Function : webcut 05982 // Member Type: PUBLIC 05983 // Description: 05984 // Author : Jane Hu 05985 // Date : 12/08 05986 //=============================================================================== 05987 CubitStatus OCCModifyEngine::webcut(DLIList<BodySM*>& webcut_body_list, 05988 const CubitVector &v1, 05989 const CubitVector &v2, 05990 const CubitVector &v3, 05991 DLIList<BodySM*>& neighbor_imprint_list, 05992 DLIList<BodySM*>& results_list, 05993 ImprintType imprint_type, 05994 bool preview ) const 05995 { 05996 CubitStatus stat; 05997 DLIList<BodySM*> new_BodySMs; 05998 05999 if(preview) 06000 { 06001 TopoDS_Face* p_face; 06002 stat = get_3_point_plane(v1, v2, v3, p_face); 06003 if(!stat) 06004 return stat; 06005 GfxPreview::clear(); 06006 OCCDrawTool::instance()->draw_TopoDS_Shape(p_face, CUBIT_BLUE_INDEX, CUBIT_TRUE); 06007 delete p_face; 06008 p_face = NULL; 06009 return CUBIT_SUCCESS; 06010 } 06011 06012 stat = OCCModifyEngine::instance()->section(webcut_body_list, v1, v2, v3, new_BodySMs, true, true,false); 06013 if(stat == CUBIT_FAILURE) 06014 { 06015 PRINT_ERROR("Can't webcut the bodies using a plane determined by 3 points.\n"); 06016 return stat; 06017 } 06018 06019 stat = OCCModifyEngine::instance()->section(webcut_body_list, v1, v2, v3, new_BodySMs, false, false, false); 06020 if(stat == CUBIT_FAILURE) 06021 { 06022 PRINT_ERROR("Can't webcut the bodies using a plane determined by 3 points.\n"); 06023 return stat; 06024 } 06025 06026 BodySM* new_body1, *new_body2; 06027 if(imprint_type > NO_IMPRINT) 06028 { 06029 for(int i = 0; i < new_BodySMs.size()-1; i ++) 06030 { 06031 BodySM* body1 = new_BodySMs[i]; 06032 for(int j = i+1; j < new_BodySMs.size(); j++) 06033 { 06034 BodySM* body2 = new_BodySMs[j]; 06035 stat = this->imprint( body1, body2, new_body1, new_body2, false); 06036 if(new_body1 && body1 != new_body1) 06037 new_BodySMs[i] = new_body1; 06038 if(new_body2 && body2 != new_body2) 06039 new_BodySMs[j] = new_body2; 06040 } 06041 } 06042 } 06043 06044 results_list = new_BodySMs; 06045 06046 //now imprint with the neighbors 06047 if( imprint_type == INCLUDE_NEIGHBORS ) 06048 { 06049 // Loop over all the neighboring Bodies 06050 DLIList<TopoDS_Shape*> shape_list1, shape_list2; 06051 DLIList<CubitBoolean> is_volume; 06052 stat = get_shape_list(neighbor_imprint_list,shape_list1,is_volume,false); 06053 if (!stat) 06054 { 06055 PRINT_WARNING("Can't imprint using neighouring bodies.\n"); 06056 return CUBIT_SUCCESS; 06057 } 06058 is_volume.clean_out(); 06059 06060 stat = get_shape_list(new_BodySMs,shape_list2,is_volume,false); 06061 { 06062 PRINT_WARNING("Can't imprint using neighouring bodies.\n"); 06063 return CUBIT_SUCCESS; 06064 } 06065 // Loop over all the neighboring shapes 06066 DLIList<TopoDS_Face*> face_list; 06067 for (int i=shape_list1.size(); i--;) 06068 { 06069 TopoDS_Shape *neighbor_shape = shape_list1.get_and_step() ; 06070 for(int j = 0; j < shape_list2.size(); j ++) 06071 { 06072 TopoDS_Shape* shape2 = shape_list2[j]; 06073 int result = this->imprint_toposhapes( shape2, neighbor_shape, 06074 face_list); 06075 if(result == 0) 06076 shape_list2[j] = shape2; 06077 } 06078 } 06079 06080 DLIList<TopologyBridge*> tbs; 06081 results_list.clean_out(); 06082 for(int j = 0; j < shape_list2.size(); j ++) 06083 { 06084 TopoDS_Shape* shape2 = shape_list2[j]; 06085 06086 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*shape2); 06087 BodySM* newBody1 = CAST_TO(tbs.get(),BodySM); 06088 results_list.append(newBody1); 06089 } 06090 } 06091 06092 return CUBIT_SUCCESS; 06093 } 06094 06095 //=============================================================================== 06096 // Function : webcuts a list of bodies using another Body as the tool. 06097 // Member Type: PUBLIC 06098 // Description: 06099 // Author : Jane Hu 06100 // Date : 01/09 06101 //=============================================================================== 06102 CubitStatus OCCModifyEngine::webcut(DLIList<BodySM*>& webcut_body_list, 06103 BodySM const* tool_body, 06104 DLIList<BodySM*>& neighbor_imprint_list, 06105 DLIList<BodySM*>& results_list, 06106 ImprintType imprint_type, 06107 bool preview ) const 06108 { 06109 // tool_body and webct_body_list will be kept and webcut result is in 06110 //results_list. 06111 //tool_body is a const pointer points to varible BodySM object 06112 //here trying to create a non-const pointer points to the same BodySM object. 06113 06114 BodySM *body = const_cast<BodySM*>(tool_body); 06115 CubitStatus stat; 06116 DLIList<BodySM*> tool_bodies; 06117 if(preview) 06118 tool_bodies.append(body); 06119 06120 BodySM *copy_tool = copy_body(body); 06121 06122 if(!preview) 06123 tool_bodies.append(copy_tool); 06124 06125 // preview the tool 06126 if (preview) 06127 { 06128 DLIList<TopoDS_Shape*> shape_list; 06129 DLIList<CubitBoolean> is_volume; 06130 stat = get_shape_list(tool_bodies,shape_list,is_volume,false); 06131 if(!stat) 06132 { 06133 PRINT_WARNING("tool_body is not an OCC body.\n"); 06134 return CUBIT_FAILURE; 06135 } 06136 GfxPreview::clear(); 06137 OCCDrawTool::instance()->draw_TopoDS_Shape(shape_list.get(), 06138 CUBIT_BLUE_INDEX, CUBIT_TRUE); 06139 06140 return CUBIT_SUCCESS; 06141 } 06142 06143 //if the tool_body is a volume, use intersect & subtract, 06144 //if it's a shell or face body, use section then. 06145 OCCBody* occ_body = CAST_TO(body, OCCBody); 06146 DLIList<Lump*> lumps; 06147 lumps = occ_body->lumps(); 06148 DLIList<OCCShell*> shells; 06149 shells = occ_body->shells(); 06150 DLIList<OCCSurface*> surfaces; 06151 surfaces = occ_body->my_sheet_surfaces(); 06152 06153 if(lumps.size() == 0 && (shells.size()==1 || surfaces.size() == 1)) 06154 { 06155 OCCSurface * surface = NULL; 06156 TopoDS_Shell* topo_shell = NULL; 06157 TopoDS_Face *topo_face = NULL; 06158 if(shells.size() == 1) 06159 { 06160 OCCShell* shell = shells.get(); 06161 surface = shell->getMemberSurfaces().get(); 06162 topo_shell = shell->get_TopoDS_Shell(); 06163 } 06164 else 06165 { 06166 surface = surfaces.get(); 06167 topo_face = surface->get_TopoDS_Face(); 06168 } 06169 CubitVector point_1, normal ; 06170 CubitStatus rsl = surface->get_point_normal(point_1, normal); 06171 assert(rsl); 06172 06173 //compare the tool body's location with the webcut_body_list, to see if 06174 //one side of the normal will totally cover one or more volumes 06175 //while the other side cut through one volume, with no whole volume 06176 //covered. Make sure the tool body's normal direct to single cut- 06177 //through volume to make sure the boolean operation won't destory 06178 //webcut_body_list and create a new body. 06179 CubitBoolean reversed = CUBIT_FALSE; 06180 if(webcut_body_list.size() == 1) 06181 { 06182 DLIList<OCCSurface*> cut_surfaces; 06183 OCCSurface* cut_face = NULL; 06184 if(surfaces.size() == 1) 06185 { 06186 cut_surfaces = occ_body->my_sheet_surfaces(); 06187 cut_face = cut_surfaces.get(); 06188 } 06189 else 06190 { 06191 DLIList<OCCShell*> shells; 06192 shells = occ_body->shells(); 06193 cut_face = shells.get()->my_surface(); 06194 } 06195 if(cut_face != NULL) 06196 { 06197 CubitVector center = cut_face->center_point(); 06198 CubitVector normal; 06199 cut_face->get_point_normal(center, normal); 06200 DLIList<Lump*> lumps; 06201 BodySM *from_body = webcut_body_list.get(); 06202 from_body->lumps(lumps); 06203 int right = 0, left = 0; 06204 for(int kk = 0; kk < lumps.size(); kk++) 06205 { 06206 CubitBox box = lumps.get_and_step()->bounding_box(); 06207 if(box <= center) //center outside of box 06208 { 06209 CubitVector v = box.center() - center; 06210 if(v%normal > 0) 06211 left ++; 06212 else 06213 right++; 06214 } 06215 } 06216 if(right > 0 && left == 0) 06217 reversed = CUBIT_TRUE; 06218 } 06219 } 06220 gp_Pnt pt = gp_Pnt( point_1.x(), point_1.y(), point_1.z()); 06221 gp_Dir normal_dir(normal.x(), normal.y(), normal.z()); 06222 gp_Vec vec(normal_dir); 06223 if(reversed) 06224 vec = -vec; 06225 pt = pt.Translated(vec); 06226 06227 TopoDS_Solid solid; 06228 if(shells.size() == 1) 06229 solid = BRepPrimAPI_MakeHalfSpace(*topo_shell, pt); 06230 else 06231 solid = BRepPrimAPI_MakeHalfSpace(*topo_face,pt); 06232 06233 DLIList<CubitBoolean> is_tool_volume; 06234 is_tool_volume.append(CUBIT_TRUE); 06235 DLIList<CubitBox*> tool_boxes ; 06236 Bnd_Box box; 06237 BRepBndLib::Add(solid, box); 06238 double min[3], max[3]; 06239 box.Get(min[0], min[1], min[2], max[0], max[1], max[2]); 06240 CubitBox* cBox = new CubitBox(min, max); 06241 06242 tool_boxes.append(cBox); 06243 DLIList<TopoDS_Shape*> solids; 06244 solids.append(&solid); 06245 rsl = do_subtract(webcut_body_list, solids, is_tool_volume, 06246 &tool_boxes, results_list, CUBIT_TRUE) ; 06247 delete cBox; 06248 if(!rsl) 06249 { 06250 PRINT_ERROR("Failed to webcut the bodies.\n"); 06251 return CUBIT_FAILURE; 06252 } 06253 gp_Vec vec2 = -2 * vec; 06254 pt = pt.Translated(vec2); 06255 if(shells.size() == 1) 06256 solid = BRepPrimAPI_MakeHalfSpace(*topo_shell, pt); 06257 else 06258 solid = BRepPrimAPI_MakeHalfSpace(*topo_face,pt); 06259 Bnd_Box box2; 06260 BRepBndLib::Add(solid, box2); 06261 box2.Get(min[0], min[1], min[2], max[0], max[1], max[2]); 06262 cBox = new CubitBox(min, max); 06263 tool_boxes.clean_out(); 06264 tool_boxes.append(cBox); 06265 solids.clean_out(); 06266 solids.append(&solid); 06267 rsl = do_subtract(webcut_body_list, solids, is_tool_volume, 06268 &tool_boxes, results_list, CUBIT_FALSE) ; 06269 //make sure the original body's pointer is the first. 06270 results_list.reverse(); 06271 delete cBox; 06272 return rsl; 06273 } 06274 06275 stat = intersect(body, webcut_body_list, results_list, 06276 CUBIT_TRUE); 06277 06278 if(!stat) 06279 { 06280 PRINT_ERROR("Failed to webcut the bodies.\n"); 06281 return CUBIT_FAILURE; 06282 } 06283 06284 bool imprint = CUBIT_TRUE; 06285 if(imprint_type == NO_IMPRINT) 06286 imprint = CUBIT_FALSE; 06287 06288 stat = subtract(tool_bodies, webcut_body_list, results_list, imprint, 06289 CUBIT_FALSE); 06290 06291 //intersect doesn't have to imprint option, so first do this imprint. 06292 BodySM* new_body1, *new_body2; 06293 if(imprint_type > NO_IMPRINT) 06294 { 06295 for(int i = 0; i < results_list.size()-1; i ++) 06296 { 06297 BodySM* body1 = results_list[i]; 06298 for(int j = i+1; j < results_list.size(); j++) 06299 { 06300 BodySM* body2 = results_list[j]; 06301 stat = this->imprint( body1, body2, new_body1, new_body2, false); 06302 if(new_body1 && body1 != new_body1) 06303 results_list[i] = new_body1; 06304 if(new_body2 && body2 != new_body2) 06305 results_list[j] = new_body2; 06306 } 06307 } 06308 } 06309 06310 //now imprint with the neighbors 06311 if( imprint_type == INCLUDE_NEIGHBORS ) 06312 { 06313 // Loop over all the neighboring Bodies 06314 DLIList<TopoDS_Shape*> shape_list1, shape_list2; 06315 DLIList<CubitBoolean> is_volume; 06316 stat = get_shape_list(neighbor_imprint_list,shape_list1,is_volume,false); 06317 if (!stat) 06318 { 06319 PRINT_WARNING("Can't imprint using neighouring bodies.\n"); 06320 return CUBIT_SUCCESS; 06321 } 06322 is_volume.clean_out(); 06323 06324 stat = get_shape_list(results_list,shape_list2,is_volume,false); 06325 { 06326 PRINT_WARNING("Can't imprint using neighouring bodies.\n"); 06327 return CUBIT_SUCCESS; 06328 } 06329 // Loop over all the neighboring shapes 06330 DLIList<TopoDS_Face*> face_list; 06331 for (int i=shape_list1.size(); i--;) 06332 { 06333 TopoDS_Shape *neighbor_shape = shape_list1.get_and_step() ; 06334 for(int j = 0; j < shape_list2.size(); j ++) 06335 { 06336 TopoDS_Shape* shape2 = shape_list2[j]; 06337 int result = this->imprint_toposhapes( shape2, neighbor_shape, face_list); 06338 if(result == 0) 06339 shape_list2[j] = shape2; 06340 } 06341 } 06342 06343 DLIList<TopologyBridge*> tbs; 06344 results_list.clean_out(); 06345 for(int j = 0; j < shape_list2.size(); j ++) 06346 { 06347 TopoDS_Shape* shape2 = shape_list2[j]; 06348 06349 tbs += OCCQueryEngine::instance()->populate_topology_bridge(*shape2); 06350 BodySM* newBody1 = CAST_TO(tbs.get(),BodySM); 06351 results_list.append(newBody1); 06352 } 06353 } 06354 return stat; 06355 } 06356 06357 //Dummy functions to fulfill the pure virtural functions in parents, should 06358 //not be called. ---Jane Hu, 02/17/2012 06359 CubitStatus OCCModifyEngine::webcut_with_sheet( 06360 DLIList<BodySM*>& webcut_body_list, 06361 BodySM *sheet_body, 06362 DLIList<BodySM*>& neighbor_imprint_list, 06363 DLIList<BodySM*> &new_bodies, 06364 ImprintType imprint_type , 06365 bool preview ) 06366 { 06367 return CUBIT_FAILURE; 06368 } 06369 06370 CubitStatus OCCModifyEngine::webcut_with_extended_sheet( 06371 DLIList<BodySM*> &webcut_body_list, 06372 DLIList<Surface*> &surface_list, 06373 DLIList<BodySM*>& neighbor_imprint_list, 06374 DLIList<BodySM*> &new_bodies, 06375 int &num_cut, 06376 ImprintType imprint_type , 06377 bool preview ) 06378 { 06379 PRINT_ERROR("This feature is not implemented.\n"); 06380 return CUBIT_FAILURE; 06381 } 06382 06383 CubitStatus OCCModifyEngine::webcut_with_sweep_curves( 06384 DLIList<BodySM*> &blank_bodies, 06385 DLIList<Curve*> &curves, 06386 const CubitVector& sweep_vector, 06387 bool through_all, 06388 Surface *stop_surf, 06389 Curve *curve_to_sweep_along, 06390 DLIList<BodySM*>& neighbor_imprint_list, 06391 DLIList<BodySM*> &results_list, 06392 ImprintType imprint_type, 06393 CubitBoolean preview ) 06394 { 06395 return CUBIT_FAILURE; 06396 } 06397 06398 CubitStatus OCCModifyEngine::webcut_with_sweep_curves_rotated( 06399 DLIList<BodySM*> &blank_bodies, 06400 DLIList<Curve*> &curves, 06401 const CubitVector &point, 06402 const CubitVector &sweep_axis, 06403 double angle, 06404 Surface *stop_surf, 06405 DLIList<BodySM*>& neighbor_imprint_list, 06406 DLIList<BodySM*> &results_list, 06407 ImprintType imprint_type, 06408 CubitBoolean preview ) 06409 { 06410 return CUBIT_FAILURE; 06411 } 06412 06413 CubitStatus OCCModifyEngine::webcut_with_sweep_surfaces_rotated( 06414 DLIList<BodySM*> &blank_bodies, 06415 DLIList<Surface*> &surfaces, 06416 const CubitVector &point, 06417 const CubitVector &sweep_axis, 06418 double angle, 06419 Surface *stop_surf, 06420 bool up_to_next, 06421 DLIList<BodySM*>& neighbor_imprint_list, 06422 DLIList<BodySM*> &results_list, 06423 ImprintType imprint_type , 06424 CubitBoolean preview ) 06425 { 06426 return CUBIT_FAILURE; 06427 } 06428 06429 CubitStatus OCCModifyEngine::webcut_with_sweep_surfaces( 06430 DLIList<BodySM*> &blank_bodies, 06431 DLIList<Surface*> &surfaces, 06432 const CubitVector& sweep_vector, 06433 bool sweep_perp, 06434 bool through_all, 06435 bool outward, 06436 bool up_to_next, 06437 Surface *stop_surf, 06438 Curve *curve_to_sweep_along, 06439 DLIList<BodySM*>& neighbor_imprint_list, 06440 DLIList<BodySM*> &results_list, 06441 ImprintType imprint_type , 06442 CubitBoolean preview ) 06443 { 06444 return CUBIT_FAILURE; 06445 } 06446 06447 CubitStatus OCCModifyEngine::webcut_with_cylinder( 06448 DLIList<BodySM*> &webcut_body_list, 06449 double radius, 06450 const CubitVector &axis, 06451 const CubitVector ¢er, 06452 DLIList<BodySM*>& neighbor_imprint_list, 06453 DLIList<BodySM*>& results_list, 06454 ImprintType imprint_type , 06455 CubitBoolean preview ) 06456 { 06457 return CUBIT_FAILURE; 06458 } 06459 06460 CubitStatus OCCModifyEngine::webcut_with_brick( 06461 DLIList<BodySM*>& webcut_body_list, 06462 const CubitVector ¢er, 06463 const CubitVector axes[3], 06464 const CubitVector &extension, 06465 DLIList<BodySM*>& neighbor_imprint_list, 06466 DLIList<BodySM*> &results_list, 06467 ImprintType imprint_type , 06468 CubitBoolean preview ) 06469 { 06470 return CUBIT_FAILURE; 06471 } 06472 06473 CubitStatus OCCModifyEngine::webcut_with_planar_sheet( 06474 DLIList<BodySM*>& webcut_body_list, 06475 const CubitVector ¢er, 06476 const CubitVector axes[2], 06477 double width, double height, 06478 DLIList<BodySM*>& neighbor_imprint_list, 06479 DLIList<BodySM*> &results_list, 06480 ImprintType imprint_type , 06481 bool preview ) 06482 { 06483 return CUBIT_FAILURE; 06484 } 06485 06486 CubitStatus OCCModifyEngine::webcut_with_curve_loop( 06487 DLIList<BodySM*> &webcut_body_list, 06488 DLIList<Curve*> &ref_edge_list, 06489 DLIList<BodySM*>& neighbor_imprint_list, 06490 DLIList<BodySM*>& results_list, 06491 ImprintType imprint_type , 06492 bool preview ) 06493 { 06494 return CUBIT_FAILURE; 06495 } 06496 06497 //=============================================================================== 06498 // Function : separate_surfaces 06499 // Member Type: PUBLIC 06500 // Description: separate surfaces in shells or compounds into independent ones, 06501 // still keep the original shell. 06502 // Author : Jane Hu 06503 // Date : 02/11 06504 //=============================================================================== 06505 CubitStatus OCCModifyEngine::separate_surfaces( DLIList<Surface*> &surf_list, 06506 DLIList<BodySM*> &new_bodies ) 06507 { 06508 DLIList<OCCSurface*> surf_need_work; 06509 //find out the complexity that the surf_list involves. 06510 for (int i = 0; i < surf_list.size(); i++) 06511 { 06512 Surface* surf = surf_list.get_and_step(); 06513 OCCSurface *surface = CAST_TO(surf, OCCSurface); 06514 OCCBody* body = surface->my_body(); 06515 if(body != NULL) //either a single surface body or a compound body 06516 { 06517 DLIList<Lump*> lumps; 06518 body->lumps(lumps); 06519 if (lumps.size() > 0) //compound body 06520 { 06521 surf_need_work.append(surface); 06522 continue; 06523 } 06524 DLIList< OCCShell*> shells; 06525 body->shells(shells); 06526 if(shells.size() > 0) //compound body 06527 surf_need_work.append(surface); 06528 continue; 06529 } 06530 06531 OCCShell* shell; 06532 shell = surface->my_shell(); 06533 if(shell != NULL && shell->my_surface() == NULL) //sheet body 06534 { 06535 surf_need_work.append(surface); 06536 continue; 06537 } 06538 } 06539 06540 //create sheet body for surf_need_work list. 06541 for(int i = 0; i < surf_need_work.size(); i++) 06542 { 06543 Surface* copy_surf = make_Surface(surf_need_work.get_and_step()); 06544 if (copy_surf == NULL) 06545 { 06546 PRINT_ERROR("Cannot create an OCC sheet bodySM from the given bodySM.\n"); 06547 return CUBIT_FAILURE; 06548 } 06549 06550 OCCSurface* occ_surf = CAST_TO(copy_surf, OCCSurface); 06551 if(occ_surf != NULL) 06552 new_bodies.append( occ_surf->my_body() ); 06553 } 06554 return CUBIT_SUCCESS; 06555 } 06556 //=============================================================================== 06557 // Function : section 06558 // Member Type: PUBLIC 06559 // Description: 06560 // Author : Jane Hu 06561 // Date : 11/08 06562 //=============================================================================== 06563 CubitStatus OCCModifyEngine::section( DLIList<BodySM*> §ion_body_list, 06564 const CubitVector &point_1, 06565 const CubitVector &point_2, 06566 const CubitVector &point_3, 06567 DLIList<BodySM*>& new_body_list, 06568 bool keep_normal_side, 06569 bool keep_old, 06570 bool keep_both_sides) 06571 { 06572 if (keep_both_sides == CUBIT_TRUE ) 06573 { 06574 PRINT_ERROR("Please use webcut to for keep both sides option.\n"); 06575 return CUBIT_FAILURE; 06576 } 06577 06578 //Calculate normal of the section plan 06579 CubitVector v1, v2, normal; 06580 v1 = point_2 - point_1; 06581 v2 = point_3 - point_1; 06582 normal = ~(v1 * v2); 06583 if(fabs(normal.length() - 1) > TOL) 06584 { 06585 PRINT_ERROR("The three points are co-linear, and can't be used as a cutting plane.\n"); 06586 return CUBIT_FAILURE; 06587 } 06588 06589 if(keep_normal_side) 06590 normal *= -1; 06591 06592 gp_Pnt pt = gp_Pnt( point_1.x(), point_1.y(), point_1.z()); 06593 gp_Dir normal_dir(normal.x(), normal.y(), normal.z()); 06594 gp_Pln plane(pt, normal_dir); 06595 gp_Vec vec(normal_dir); 06596 pt = pt.Translated(vec); 06597 06598 TopoDS_Face face = BRepBuilderAPI_MakeFace(plane); 06599 TopoDS_Solid solid = BRepPrimAPI_MakeHalfSpace(face, pt); 06600 06601 DLIList<CubitBoolean> is_tool_volume; 06602 is_tool_volume.append(CUBIT_TRUE); 06603 DLIList<CubitBox*> tool_boxes ; 06604 Bnd_Box box; 06605 BRepBndLib::Add(solid, box); 06606 double min[3], max[3]; 06607 box.Get(min[0], min[1], min[2], max[0], max[1], max[2]); 06608 CubitBox* cBox = new CubitBox(min, max); 06609 06610 tool_boxes.append(cBox); 06611 DLIList<TopoDS_Shape*> solids; 06612 solids.append(&solid); 06613 CubitStatus stat = do_subtract(section_body_list, solids, is_tool_volume, 06614 &tool_boxes, new_body_list, keep_old) ; 06615 delete cBox; 06616 return stat; 06617 } 06618 06619 //=============================================================================== 06620 // Function : split_body 06621 // Member Type: PUBLIC 06622 // Description: Splits multiple lumps in one body into separate bodies 06623 // Author : Jane Hu 06624 // Date : 12/08 06625 //=============================================================================== 06626 CubitStatus OCCModifyEngine::split_body( BodySM *body_ptr, 06627 DLIList<BodySM*> &new_bodies ) 06628 { 06629 OCCBody* occ_body = CAST_TO(body_ptr, OCCBody); 06630 if(!occ_body) 06631 { 06632 PRINT_ERROR("This is not an OCC body to be split.\n"); 06633 return CUBIT_FAILURE; 06634 } 06635 DLIList<Lump*> lumps = occ_body->lumps(); 06636 if(lumps.size() == 1) 06637 { 06638 new_bodies.append(body_ptr); 06639 return CUBIT_SUCCESS; 06640 } 06641 for(int i = 0; i < lumps.size(); i++) 06642 { 06643 Lump* lump = lumps.get_and_step(); 06644 OCCLump* occ_lump = CAST_TO(lump, OCCLump); 06645 OCCSurface* occ_surface = occ_lump->my_sheet_surface(); 06646 //first delete the body which bounds all the stuff. 06647 if (i == 0) 06648 OCCQueryEngine::instance()->unhook_BodySM_from_OCC(body_ptr, CUBIT_FALSE); 06649 if(occ_surface) 06650 { 06651 TopoDS_Face* face = occ_surface->get_TopoDS_Face(); 06652 Surface* surface = 06653 OCCQueryEngine::instance()->populate_topology_bridge(*face, 06654 CUBIT_TRUE); 06655 new_bodies.append(CAST_TO(surface, OCCSurface)->my_body()); 06656 continue; 06657 } 06658 OCCShell* occ_shell = occ_lump->my_shell(); 06659 if(occ_shell) 06660 { 06661 TopoDS_Shell* shell = occ_shell->get_TopoDS_Shell(); 06662 OCCShell* ashell = 06663 OCCQueryEngine::instance()->populate_topology_bridge(*shell, 06664 CUBIT_TRUE); 06665 new_bodies.append(ashell->my_body()); 06666 continue; 06667 } 06668 else 06669 { 06670 TopoDS_Solid* solid = occ_lump->get_TopoDS_Solid(); 06671 Lump* alump = 06672 OCCQueryEngine::instance()->populate_topology_bridge(*solid, 06673 CUBIT_TRUE); 06674 new_bodies.append(CAST_TO(alump,OCCLump)->get_body()); 06675 continue; 06676 } 06677 } 06678 06679 if(lumps.size() > 1) 06680 delete body_ptr; 06681 return CUBIT_SUCCESS; 06682 } 06683 06684 06685 //=============================================================================== 06686 // Function : reverse_body 06687 // Member Type: PUBLIC 06688 // Description: Turn body inside-out 06689 // Author : Jane Hu 06690 // Date : 03/03/09 06691 //=============================================================================== 06692 CubitStatus OCCModifyEngine::reverse_body( BodySM* body_ptr ) 06693 { 06694 OCCBody* occ_body = CAST_TO(body_ptr, OCCBody); 06695 if (!occ_body) 06696 { 06697 PRINT_ERROR("Cannot reverse a non-OCC bodySM .\n" 06698 "Possible incompatible geometry engines.\n"); 06699 return CUBIT_FAILURE; 06700 } 06701 06702 TopoDS_Shape* orig_S; 06703 TopoDS_Shape S; 06704 BRep_Builder B; 06705 occ_body->get_TopoDS_Shape(orig_S); 06706 S = orig_S->EmptyCopied(); 06707 TopoDS_Iterator it(*orig_S); 06708 while (it.More()) { 06709 B.Add(S,it.Value().Reversed()); 06710 it.Next(); 06711 } 06712 occ_body->set_TopoDS_Shape(TopoDS::Compound(S)); 06713 //Bind the new shape and its underlining sub-shapes. 06714 TopExp_Explorer Ex_orig, Ex; 06715 int k = -1; 06716 Ex.Init(S, TopAbs_COMPOUND); 06717 Ex_orig.Init(*orig_S, TopAbs_COMPOUND); 06718 for (; Ex_orig.More(), Ex.More(); Ex_orig.Next(), Ex.Next()) 06719 { 06720 if(OCCQueryEngine::instance()->OCCMap->IsBound(Ex.Current())) 06721 { 06722 k = OCCQueryEngine::instance()->OCCMap->Find(Ex_orig.Current()); 06723 OCCQueryEngine::instance()->OCCMap->UnBind(Ex_orig.Current()); 06724 OCCQueryEngine::instance()->OCCMap->Bind(Ex.Current(), k); 06725 TopExp_Explorer Ex_old_solid, Ex_solid; 06726 Ex_old_solid.Init(*orig_S,TopAbs_SOLID); 06727 Ex_solid.Init(S, TopAbs_SOLID); 06728 DLIList<Lump*> lumps = occ_body->lumps(); 06729 for (; Ex_old_solid.More(), Ex_solid.More(); Ex_old_solid.Next(), Ex_solid.Next()) 06730 { 06731 k = OCCQueryEngine::instance()->OCCMap->Find(Ex_old_solid.Current()); 06732 OCCQueryEngine::instance()->OCCMap->UnBind(Ex_old_solid.Current()); 06733 OCCQueryEngine::instance()->OCCMap->Bind(Ex_solid.Current(), k); 06734 OCCLump* occ_lump = CAST_TO(lumps.get_and_step(), OCCLump); 06735 occ_lump->set_TopoDS_Solid(TopoDS::Solid(Ex_solid.Current())); 06736 } 06737 } 06738 06739 else 06740 { 06741 Lump *lump = occ_body->lumps().get(); 06742 OCCLump* occ_lump = CAST_TO(lump, OCCLump); 06743 TopoDS_Solid solid = *(occ_lump->get_TopoDS_Solid()); 06744 k = OCCQueryEngine::instance()->OCCMap->Find(solid); 06745 OCCQueryEngine::instance()->OCCMap->UnBind(solid); 06746 TopExp_Explorer Ex_local; 06747 Ex_local.Init(S, TopAbs_SOLID); 06748 OCCQueryEngine::instance()->OCCMap->Bind(Ex_local.Current(), k); 06749 occ_lump->set_TopoDS_Solid(TopoDS::Solid(Ex_local.Current())); 06750 } 06751 } 06752 06753 Ex.Init(S, TopAbs_SHELL); 06754 Ex_orig.Init(*orig_S, TopAbs_SHELL); 06755 for (; Ex_orig.More(), Ex.More(); Ex_orig.Next(), Ex.Next()) 06756 { 06757 k = OCCQueryEngine::instance()->OCCMap->Find(Ex_orig.Current()); 06758 OCCQueryEngine::instance()->OCCMap->UnBind(Ex_orig.Current()); 06759 OCCQueryEngine::instance()->OCCMap->Bind(Ex.Current(), k); 06760 OCCShell *shell = (OCCShell*)(OCCQueryEngine::instance()->OccToCGM->find(k))->second; 06761 shell->set_TopoDS_Shell(TopoDS::Shell(Ex.Current())); 06762 } 06763 06764 Ex.Init(S, TopAbs_FACE); 06765 Ex_orig.Init(*orig_S, TopAbs_FACE); 06766 for (; Ex_orig.More(), Ex.More(); Ex_orig.Next(), Ex.Next()) 06767 { 06768 k = OCCQueryEngine::instance()->OCCMap->Find(Ex_orig.Current()); 06769 OCCQueryEngine::instance()->OCCMap->UnBind(Ex_orig.Current()); 06770 OCCQueryEngine::instance()->OCCMap->Bind(Ex.Current(), k); 06771 OCCSurface *surface = (OCCSurface *)(OCCQueryEngine::instance()->OccToCGM->find(k))->second; 06772 TopoDS_Face face = TopoDS::Face(Ex.Current()); 06773 surface->set_TopoDS_Face(face); 06774 } 06775 06776 Ex.Init(S, TopAbs_WIRE); 06777 Ex_orig.Init(*orig_S, TopAbs_WIRE); 06778 for (; Ex_orig.More(), Ex.More(); Ex_orig.Next(), Ex.Next()) 06779 { 06780 k = OCCQueryEngine::instance()->OCCMap->Find(Ex_orig.Current()); 06781 OCCQueryEngine::instance()->OCCMap->UnBind(Ex_orig.Current()); 06782 OCCQueryEngine::instance()->OCCMap->Bind(Ex.Current(), k); 06783 OCCLoop* wire = (OCCLoop*)(OCCQueryEngine::instance()->OccToCGM->find(k))->second; 06784 wire->set_TopoDS_Wire(TopoDS::Wire(Ex.Current())); 06785 } 06786 06787 Ex.Init(S, TopAbs_EDGE); 06788 Ex_orig.Init(*orig_S, TopAbs_EDGE); 06789 for (; Ex_orig.More(), Ex.More(); Ex_orig.Next(), Ex.Next()) 06790 { 06791 k = OCCQueryEngine::instance()->OCCMap->Find(Ex_orig.Current()); 06792 OCCQueryEngine::instance()->OCCMap->UnBind(Ex_orig.Current()); 06793 OCCQueryEngine::instance()->OCCMap->Bind(Ex.Current(), k); 06794 OCCCurve* edge = (OCCCurve*)(OCCQueryEngine::instance()->OccToCGM->find(k))->second; 06795 edge->set_TopoDS_Edge(TopoDS::Edge(Ex.Current())); 06796 } 06797 06798 Ex.Init(S, TopAbs_VERTEX); 06799 Ex_orig.Init(*orig_S, TopAbs_VERTEX); 06800 for (; Ex_orig.More(), Ex.More(); Ex_orig.Next(), Ex.Next()) 06801 { 06802 k = OCCQueryEngine::instance()->OCCMap->Find(Ex_orig.Current()); 06803 OCCQueryEngine::instance()->OCCMap->UnBind(Ex_orig.Current()); 06804 OCCQueryEngine::instance()->OCCMap->Bind(Ex.Current(), k); 06805 OCCPoint* point = (OCCPoint*)(OCCQueryEngine::instance()->OccToCGM->find(k))->second; 06806 point->set_TopoDS_Vertex(TopoDS::Vertex(Ex.Current())); 06807 } 06808 return CUBIT_SUCCESS; 06809 } 06810 06811 06812 06813 //=============================================================================== 06814 // Function : split_periodic 06815 // Member Type: PUBLIC 06816 // Description: 06817 // Author : John Fowler 06818 // Date : 10/02 06819 //=============================================================================== 06820 CubitStatus OCCModifyEngine::split_periodic( BodySM * /*body_ptr*/, 06821 BodySM *& /*new_body*/ ) 06822 { 06823 return CUBIT_FAILURE; 06824 } 06825 06826 //=============================================================================== 06827 // Function : regularize_body 06828 // Member Type: PUBLIC 06829 // Description: 06830 // Author : John Fowler 06831 // Date : 10/02 06832 //=============================================================================== 06833 CubitStatus OCCModifyEngine::regularize_body( BodySM * /*body_ptr*/, 06834 BodySM *& /*new_body_ptr*/ ) 06835 { 06836 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 06837 return CUBIT_FAILURE; 06838 } 06839 06840 //=============================================================================== 06841 // Function : regularize_refentity 06842 // Member Type: PUBLIC 06843 // Description: 06844 // Author : John Fowler 06845 // Date : 10/02 06846 //=============================================================================== 06847 CubitStatus OCCModifyEngine::regularize_entity( GeometryEntity * /*old_entity_ptr*/, 06848 BodySM *& /*new_body_ptr*/ ) 06849 { 06850 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 06851 return CUBIT_FAILURE; 06852 } 06853 06854 //=============================================================================== 06855 // Function : offset_curves 06856 // Member Type: PUBLIC 06857 // Description: 06858 // Author : Jane Hu 06859 // Date : 12/08 06860 //=============================================================================== 06861 CubitStatus OCCModifyEngine::offset_curves( DLIList<Curve*>& curves, 06862 DLIList<Curve*>& new_curves, 06863 double offset_distance, 06864 const CubitVector& offset_direction, 06865 int gap_type ) 06866 { 06867 //gap_type has no effect here. 06868 if( curves.size() == 1 && (offset_direction.x() || 06869 offset_direction.y() || offset_direction.z()) ) 06870 { 06871 gp_Dir offset(offset_direction.x(), offset_direction.y(), offset_direction.z()); 06872 //check if the curve is straight, error out for non-straight curve. 06873 Curve* curve = curves.get(); 06874 OCCCurve* occ_curve = CAST_TO(curve, OCCCurve); 06875 if(occ_curve->geometry_type() == STRAIGHT_CURVE_TYPE) 06876 { 06877 //based on the definitions of the offset curve on OCC, calculate the 06878 //offset direction to make it consistant with 06879 double u1, u2; 06880 occ_curve->get_param_range(u1, u2); 06881 CubitVector p1, p2, tangent; 06882 occ_curve->position_from_u(u1, p1); 06883 occ_curve->position_from_u(u2, p2); 06884 tangent = p2 -p1; 06885 CubitVector cal_offset_dir = offset_direction * tangent; 06886 gp_Dir offset(cal_offset_dir.x(), cal_offset_dir.y(), cal_offset_dir.z()); 06887 TopoDS_Edge * edge = occ_curve->get_TopoDS_Edge(); 06888 Standard_Real first; 06889 Standard_Real last; 06890 Handle(Geom_Curve) myCurve = BRep_Tool::Curve(*edge, first, last); 06891 Handle(Geom_OffsetCurve) new_curve = 06892 new Geom_OffsetCurve(myCurve,offset_distance, offset); 06893 if(!new_curve) 06894 { 06895 TopologyEntity *entity = curve->topology_entity(); 06896 BasicTopologyEntity *bte = CAST_TO(entity, BasicTopologyEntity); 06897 PRINT_ERROR("Can't create offset curve for curve %d.\n", bte->id()); 06898 return CUBIT_FAILURE; 06899 } 06900 TopoDS_Edge new_edge = BRepBuilderAPI_MakeEdge(new_curve, u1, u2); 06901 Curve* offset_curve = OCCQueryEngine::instance()->populate_topology_bridge(new_edge, CUBIT_TRUE); 06902 new_curves.append(offset_curve); 06903 return CUBIT_SUCCESS; 06904 } 06905 else 06906 PRINT_WARNING( "Direction qualifier ignored - only valid for one straight curve\n" ); 06907 } 06908 06909 else if( offset_direction.x() || offset_direction.y() || offset_direction.z() ) 06910 PRINT_WARNING( "Direction qualifier ignored - only valid for one straight curve\n" ); 06911 06912 else if (offset_direction.x() == 0.0 && offset_direction.y() == 0.0 && 06913 offset_direction.z() == 0.0) 06914 { 06915 for(int i = 0 ; i < curves.size(); i++) 06916 { 06917 Curve* curve = curves.get_and_step(); 06918 OCCCurve* occ_curve = CAST_TO(curve, OCCCurve); 06919 if(occ_curve->geometry_type() == STRAIGHT_CURVE_TYPE) 06920 { 06921 // TODO: Remove this condition? 06922 // A planar nonlinear wire consisting of straight curves can be offset 06923 // but it isn't clear that the intent was to offset a wire instead 06924 // of each curve individually. 06925 PRINT_ERROR("Must have an offset direction for any straight curve.\n"); 06926 return CUBIT_FAILURE; 06927 } 06928 } 06929 } 06930 //make wire out of ref_edge_list 06931 BRepBuilderAPI_MakeWire awire; 06932 TopTools_ListOfShape L; 06933 OCCCurve* occ_curve = NULL; 06934 BRepBuilderAPI_Copy shapeCopier; 06935 for(int i = 0 ; i < curves.size(); i++) 06936 { 06937 Curve* curve = curves.get_and_step(); 06938 occ_curve = CAST_TO(curve, OCCCurve); 06939 if(!occ_curve) 06940 continue; 06941 shapeCopier.Perform(*(occ_curve->get_TopoDS_Edge())); 06942 L.Append(shapeCopier.Shape()); 06943 } 06944 06945 awire.Add(L); 06946 if(awire.Error()) 06947 { 06948 PRINT_ERROR("Curves must form a planar chain in order for offset to work.\n"); 06949 return CUBIT_FAILURE; 06950 } 06951 TopoDS_Wire wire; 06952 wire = awire.Wire(); 06953 06954 #if OCC_VERSION_MAJOR < 6 || (OCC_VERSION_MAJOR == 6 && OCC_VERSION_MINOR < 8) 06955 CubitBoolean closed = wire.Closed(); 06956 BRepOffsetAPI_MakeOffset offCurveBuilder(wire); 06957 offCurveBuilder.Perform(offset_distance); 06958 offCurveBuilder.Build(); 06959 06960 // Prior to OCC version 6.8 / OCE version 0.17 06961 // For an open wire: 06962 // It returns a closed wire, with two connecting curves and a positive offset 06963 // curve list and a negative offset curve list. 06964 // For a closed wire: 06965 // It returns a closed wire outside the original one if offset_distance > 0 06966 // It returns a closed wire inside the original one if offset_distance < 0 06967 06968 TopoDS_Shape offWireShape = offCurveBuilder.Shape(); 06969 wire = TopoDS::Wire(offWireShape); 06970 06971 if (!closed) 06972 { 06973 int num_curves = countEdges(wire); 06974 if (num_curves != (2 + 2*curves.size()) ) 06975 { 06976 PRINT_ERROR("Opencascade can't calculate one offset curve for each" 06977 " input curve. It's a limitation, try to use another type" 06978 " of curve to offset.\n"); 06979 return CUBIT_FAILURE; 06980 } 06981 06982 BRepTools_WireExplorer Ex(wire); 06983 Ex.Next(); // omit the initial cap/connecting curve 06984 for (int i = 0; i < curves.size(); ++i) 06985 { 06986 TopoDS_Edge new_edge = Ex.Current(); 06987 Curve* curve = curves.get_and_step(); 06988 Curve* offset_curve = OCCQueryEngine::instance()-> 06989 populate_topology_bridge(new_edge, CUBIT_TRUE); 06990 // double check here to make sure we get the correct offset curve 06991 // which is if the offset_distance is positive, the new curve should 06992 // be longer than the original curve. 06993 if (i == 0) 06994 { 06995 double d_offset = offset_curve->measure(); 06996 double d_orig = curve->measure(); 06997 if ((offset_distance > 0 && d_offset < d_orig) || 06998 (offset_distance < 0 && d_offset > d_orig)) 06999 { 07000 for (int j = 0; j < curves.size(); ++j) 07001 { 07002 Ex.Next(); 07003 } 07004 Ex.Next(); 07005 } 07006 new_edge = Ex.Current(); 07007 offset_curve = OCCQueryEngine::instance()-> 07008 populate_topology_bridge(new_edge, CUBIT_TRUE); 07009 } 07010 new_curves.append(offset_curve); 07011 Ex.Next(); 07012 } 07013 07014 // successful offset of open wire 07015 return CUBIT_SUCCESS; 07016 } 07017 07018 // if wire is closed 07019 for (BRepTools_WireExplorer Ex(wire); Ex.More(); Ex.Next()) 07020 { 07021 TopoDS_Edge new_edge = Ex.Current(); 07022 Curve* offset_curve = OCCQueryEngine::instance()-> 07023 populate_topology_bridge(new_edge, CUBIT_TRUE); 07024 new_curves.append(offset_curve); 07025 } 07026 07027 // successful offset of closed wire 07028 return CUBIT_SUCCESS; 07029 07030 #else 07031 07032 // The behavior changed as of OCC 6.8 and OCE 0.17. 07033 // Not all cases have been tested. 07034 // Documentation in BRepFill_OffsetWire, which is used by 07035 // BRepOffsetAPI_MakeOffset, says that an offset will be "to the left" 07036 // of the spine wire, with each point at the specified offset from the 07037 // the closest point on the original wire. 07038 // Negative offsets are "to the right." 07039 // "Left" and "right" imply a normal direction on the face that contains 07040 // the wire. 07041 // The contract for this method in CGM is not documented well, but the 07042 // previous implementation suggests that a negative offset is intended 07043 // to return the shorter of the two open offset curves. That may not be 07044 // well defined, and is hard to interpret when there are multiple 07045 // edges in the wire. 07046 // 07047 // When testing the offset functionality in a recent release version of 07048 // Cubit, it seemed that the direction of the offset depends on 07049 // how the wire turns. If a closed wire has a positive turning number or 07050 // an open wire has what might be called a positive turning angle, then 07051 // the positive offset is to the right. If the turning angle was 07052 // negative, then the positive offset was consistently to the left. 07053 // This behavior is independent of normal direction, since what appears 07054 // to be right and positive turning angle from one normal direction becomes 07055 // left and negative turning angle when the normal direction is flipped. 07056 07057 // The current implementation here returns the result only if the number of 07058 // offset curves matches the number of input curves for both the 07059 // positive and negative offset. In that situation, both the positive 07060 // and negative offsets are computed, the length of each wire is 07061 // computed, and the shorter result is returned if the offset is 07062 // negative. The longer result is returned if the offset is positive. 07063 // If the lengths are equal then the curve(s) that OCC computed for the 07064 // offset with the same sign as the input offset are used. This is 07065 // quite different from the behavior of Cubit, but passes the previously 07066 // existing offset_curves test and agrees with the local in-method 07067 // documentation that existed prior to OCC 6.8. 07068 07069 // The WireExplorer is used in this method, which may miss some edges 07070 // if the result wire does not have all edges connected end to end. 07071 07072 double positiveOffset = fabs(offset_distance); 07073 BRepOffsetAPI_MakeOffset posOffCurveBldr(wire); 07074 // Using an open offset, as in the following line, seems to produce results 07075 // closer to the original intent of this method, but the original behavior is 07076 // preserved better with the default Standard_False closed offset. 07077 // BRepOffsetAPI_MakeOffset posOffCurveBldr(wire, GeomAbs_Arc, Standard_True); 07078 posOffCurveBldr.Perform(positiveOffset); 07079 TopoDS_Shape posOffShape = posOffCurveBldr.Shape(); 07080 TopoDS_Wire posOffWire = TopoDS::Wire(posOffShape); 07081 if (countEdges(posOffWire) != curves.size()) 07082 { 07083 PRINT_ERROR("The number of positive offset curves computed by the OCE" 07084 " geometry engine does not equal the number of curves in" 07085 " the input.\n"); 07086 // Remark: It appears to be possible to match curves in the output 07087 // to curves in the input by calling BRepOffsetAPI_MakeOffset::Generated. 07088 // One could also directly use BRepFill_OffsetWire. 07089 // Perhaps compounds curves could be constructed to make the 07090 // result curves match the input. 07091 return CUBIT_FAILURE; 07092 } 07093 07094 double negativeOffset = -1.0*positiveOffset; 07095 BRepOffsetAPI_MakeOffset negOffCurveBldr(wire); 07096 // Using an open offset, as in the following line, seems to produce results 07097 // closer to the original intent of this method, but the original behavior is 07098 // preserved better with the default Standard_False closed offset. 07099 // BRepOffsetAPI_MakeOffset negOffCurveBldr(wire, GeomAbs_Arc, Standard_True); 07100 negOffCurveBldr.Perform(negativeOffset); 07101 TopoDS_Shape negOffShape = negOffCurveBldr.Shape(); 07102 TopoDS_Wire negOffWire = TopoDS::Wire(negOffShape); 07103 if (countEdges(negOffWire) != curves.size()) 07104 { 07105 PRINT_ERROR("The number of negative offset curves computed by the OCE" 07106 " geometry engine does not equal the number of curves in" 07107 " the input.\n"); 07108 return CUBIT_FAILURE; 07109 } 07110 07111 // compute wire lengths and choose which wire to return 07112 TopoDS_Wire* wirePtrs[2]; 07113 double wireLengths[2]; 07114 wirePtrs[0] = &posOffWire; 07115 wirePtrs[1] = &negOffWire; 07116 wireLengths[0] = wireLengths[1] = 0.0; 07117 07118 for (int wireIndex = 0; wireIndex < 2; ++wireIndex) 07119 { 07120 TopoDS_Wire* wirePtr = wirePtrs[wireIndex]; 07121 double wireLen = 0.0; 07122 for (BRepTools_WireExplorer Ex(*wirePtr); Ex.More(); Ex.Next()) 07123 { 07124 GProp_GProps edgeProps; 07125 BRepGProp::LinearProperties(Ex.Current(), edgeProps); 07126 wireLen += edgeProps.Mass(); 07127 } 07128 wireLengths[wireIndex] = wireLen; 07129 } 07130 07131 TopoDS_Wire* chosenWirePtr = wirePtrs[0]; 07132 if (offset_distance >= 0) 07133 { 07134 if (wireLengths[1] > wireLengths[0]) 07135 chosenWirePtr = wirePtrs[1]; 07136 } 07137 else if (wireLengths[1] <= wireLengths[0]) 07138 chosenWirePtr = wirePtrs[1]; 07139 07140 for (BRepTools_WireExplorer Ex(*chosenWirePtr); Ex.More(); Ex.Next()) 07141 { 07142 Curve* offset_curve = OCCQueryEngine::instance()-> 07143 populate_topology_bridge(Ex.Current(), CUBIT_TRUE); 07144 new_curves.append(offset_curve); 07145 } 07146 return CUBIT_SUCCESS; 07147 #endif 07148 } 07149 07150 //============================================================================= 07151 // Function : countEdges 07152 // Member Type: private 07153 // Description: Count the number of edges encountered by a 07154 // BRepTools_WireExplorer exploration of the specified wire. 07155 //============================================================================= 07156 int OCCModifyEngine::countEdges(TopoDS_Wire &wire) 07157 { 07158 int numEdges = 0; 07159 for (BRepTools_WireExplorer Ex(wire); Ex.More(); Ex.Next()) 07160 ++numEdges; 07161 return numEdges; 07162 } 07163 07164 //=============================================================================== 07165 // Function : trim_curve 07166 // Member Type: PUBLIC 07167 // Description: 07168 // Author : Jane Hu 07169 // Date : 12/08 07170 //=============================================================================== 07171 Curve* OCCModifyEngine::trim_curve( Curve* trim_curve, 07172 const CubitVector& trim_vector, 07173 const CubitVector& keep_vector, 07174 bool keep ) 07175 { 07176 OCCCurve* occ_crv = CAST_TO(trim_curve, OCCCurve); 07177 if(!occ_crv) 07178 { 07179 PRINT_ERROR("This is not a OCC curve to be trimmed.\n"); 07180 return (Curve*)NULL; 07181 } 07182 07183 //Determine the trimmed curve's parameter range. 07184 double u1, u2; 07185 occ_crv->get_param_range(u1, u2); 07186 double trim_u = occ_crv->u_from_position(trim_vector); 07187 double keep_u = occ_crv->u_from_position(keep_vector); 07188 if(trim_u > u2+TOL || trim_u < u1 - TOL) 07189 { 07190 PRINT_ERROR("The trim_vector is outside of the curve range.\n"); 07191 return (Curve*)NULL; 07192 } 07193 07194 if(keep_u > trim_u ) 07195 u1 = trim_u; 07196 else if(keep_u < trim_u) 07197 u2 = trim_u; 07198 07199 else 07200 { 07201 PRINT_ERROR("Can't determine which part of the curve to be kept.\n"); 07202 return (Curve*)NULL; 07203 } 07204 //get the Geom_Curve of the OCCCurve 07205 TopoDS_Edge * edge = occ_crv->get_TopoDS_Edge(); 07206 Standard_Real first; 07207 Standard_Real last; 07208 Handle(Geom_Curve) myCurve = BRep_Tool::Curve(*edge, first, last); 07209 07210 //Trim the curve 07211 TopoDS_Edge t_edge = BRepBuilderAPI_MakeEdge(myCurve, u1, u2); 07212 Curve* t_curve = OCCQueryEngine::instance()->populate_topology_bridge(t_edge, CUBIT_TRUE); 07213 if(!keep) 07214 { 07215 DLIList<OCCLoop*> loops = occ_crv->loops(); 07216 if(loops.size() == 0) 07217 OCCQueryEngine::instance()->delete_solid_model_entities(trim_curve); 07218 } 07219 return t_curve; 07220 } 07221 07222 //=============================================================================== 07223 // Function : create_body_from_surfs 07224 // Member Type: PUBLIC 07225 // Description: 07226 // Author : Jane Hu 07227 // Date : 4/22/08 07228 //=============================================================================== 07229 CubitStatus OCCModifyEngine::create_solid_bodies_from_surfs(DLIList<Surface*> & ref_face_list, 07230 DLIList<BodySM*>& new_bodies, 07231 bool keep_old, 07232 bool heal, 07233 bool sheet) const 07234 { 07235 //keep_old and heal are ignored, always delete old. 07236 //all surfaces should be stand along surface bodies or shell bodies' surface 07237 CubitStatus stat = CUBIT_SUCCESS; 07238 if(!sheet) 07239 { 07240 Lump* lump = make_Lump(ref_face_list); 07241 if (!lump) 07242 return CUBIT_FAILURE; 07243 07244 new_bodies.append(CAST_TO(lump, OCCLump)->get_body()); 07245 } 07246 07247 else 07248 { 07249 DLIList<BodySM*> bodies; 07250 for(int i = 0 ; i < ref_face_list.size(); i++) 07251 { 07252 OCCSurface* surf = CAST_TO(ref_face_list.get_and_step(), OCCSurface); 07253 BodySM* body = surf->my_body(); 07254 if(body) 07255 bodies.append_unique(body); 07256 } 07257 stat = unite(bodies, new_bodies, keep_old); 07258 } 07259 return stat; 07260 } 07261 07262 //=============================================================================== 07263 // Function : create_arc_three 07264 // Member Type: PUBLIC 07265 // Description: 07266 // Author : Jane Hu 07267 // Date : 12/08 07268 //=============================================================================== 07269 Curve* OCCModifyEngine::create_arc_three( TBPoint* pt1, 07270 TBPoint* pt2, 07271 TBPoint* pt3, 07272 bool full, 07273 bool preview ) 07274 { 07275 Curve* new_curve = NULL; 07276 if(!full) 07277 { 07278 CubitVector v2(pt2->coordinates()); 07279 new_curve = const_cast<OCCModifyEngine*> (this)-> 07280 make_Curve(ARC_CURVE_TYPE,pt1,pt3, &v2); 07281 } 07282 else 07283 { 07284 CubitVector v1(pt1->coordinates()); 07285 CubitVector v2(pt2->coordinates()); 07286 CubitVector v3(pt3->coordinates()); 07287 07288 gp_Pnt gp_pt1(v1.x(),v1.y(), v1.z()); 07289 gp_Pnt gp_pt2(v2.x(),v2.y(), v2.z()); 07290 gp_Pnt gp_pt3(v3.x(),v3.y(), v3.z()); 07291 07292 Handle(Geom_Circle) curve_ptr; 07293 curve_ptr = GC_MakeCircle(gp_pt1,gp_pt2,gp_pt3); 07294 07295 OCCPoint* occ_pt1 = CAST_TO(const_cast<TBPoint*>(pt1),OCCPoint); 07296 TopoDS_Vertex * vt1 = occ_pt1->get_TopoDS_Vertex(); 07297 TopoDS_Edge new_edge = BRepBuilderAPI_MakeEdge(curve_ptr, *vt1, *vt1); 07298 new_curve = OCCQueryEngine::instance()->populate_topology_bridge(new_edge, 07299 CUBIT_TRUE); 07300 } 07301 if(preview) 07302 { 07303 GfxPreview::clear(); 07304 OCCCurve* occ_curve = CAST_TO(new_curve, OCCCurve); 07305 TopoDS_Edge* h_edge = occ_curve->get_TopoDS_Edge(); 07306 // Draw this edge 07307 OCCDrawTool::instance()->draw_EDGE( h_edge, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 07308 07309 OCCQueryEngine::instance()->delete_solid_model_entities(new_curve); 07310 return (Curve*) NULL; 07311 } 07312 else 07313 return new_curve; 07314 } 07315 07316 //=============================================================================== 07317 // Function : create_arc_three 07318 // Member Type: PUBLIC 07319 // Description: 07320 // Author : Jane Hu 07321 // Date : 12/08 07322 //=============================================================================== 07323 Curve* OCCModifyEngine::create_arc_three( Curve* curve1, 07324 Curve* curve2, 07325 Curve* curve3, 07326 bool full, 07327 bool preview ) 07328 { 07329 OCCCurve* occ_crv1 = CAST_TO(curve1, OCCCurve); 07330 OCCCurve* occ_crv2 = CAST_TO(curve2, OCCCurve); 07331 OCCCurve* occ_crv3 = CAST_TO(curve3, OCCCurve); 07332 GeometryType type1 = occ_crv1->geometry_type(); 07333 GeometryType type2 = occ_crv2->geometry_type(); 07334 GeometryType type3 = occ_crv3->geometry_type(); 07335 if(type1 != STRAIGHT_CURVE_TYPE || type2 != STRAIGHT_CURVE_TYPE || 07336 type3 != STRAIGHT_CURVE_TYPE) 07337 { 07338 PRINT_WARNING("Need three straight curves to calculate incenter.\n"); 07339 return (Curve*) NULL; 07340 } 07341 07342 //0.check that non of the curves are parallel of each other. 07343 DLIList<CubitVector> intscts; 07344 CubitVector vt1, vt2, vt3; 07345 CubitBoolean none = CUBIT_FALSE; 07346 OCCQueryEngine::instance()->get_intersections(curve1, curve2, intscts,none,none); 07347 vt1 = intscts.get(); 07348 intscts.clean_out(); 07349 OCCQueryEngine::instance()->get_intersections(curve2,curve3, intscts,none,none); 07350 vt2 = intscts.get(); 07351 intscts.clean_out(); 07352 OCCQueryEngine::instance()->get_intersections(curve3, curve1, intscts,none,none); 07353 vt3 = intscts.get(); 07354 07355 double u11, u12, u21, u22, u31, u32; 07356 occ_crv1->get_param_range(u11, u12); 07357 occ_crv2->get_param_range(u21, u22); 07358 occ_crv3->get_param_range(u31, u32); 07359 07360 CubitVector tangent1, tangent2, tangent3; 07361 occ_crv1->get_tangent(vt1, tangent1); 07362 occ_crv2->get_tangent(vt2, tangent2); 07363 occ_crv3->get_tangent(vt3, tangent3); 07364 07365 CubitVector normal1 = tangent1 * tangent2; 07366 CubitVector normal2 = tangent2 * tangent3; 07367 CubitVector normal3 = tangent3 * tangent1; 07368 if( normal1.length()< TOL || normal2.length()< TOL || 07369 normal3.length() < TOL ) 07370 { 07371 PRINT_WARNING("Three curves must be able to form a triangle.\n"); 07372 return (Curve*) NULL; 07373 } 07374 07375 //normals must parallel to each other, meaning all curves must be on 07376 //the same plane. 07377 normal1.normalize(); 07378 normal2.normalize(); 07379 normal3.normalize(); 07380 07381 CubitVector parallel1 = normal1 * normal2; 07382 CubitVector parallel2 = normal2 * normal3; 07383 CubitVector parallel3 = normal3 * normal1; 07384 if(parallel1.length() > TOL || parallel2.length() > TOL || 07385 parallel3.length() > TOL) 07386 { 07387 PRINT_WARNING("Three curves must be able to form a triangle.\n"); 07388 return (Curve*) NULL; 07389 } 07390 //1.find the angle between each of the two curves 07391 double angle1, angle2, angle3; 07392 angle1 = tangent1.interior_angle(tangent2); 07393 angle2 = tangent2.interior_angle(tangent3); 07394 angle3 = tangent3.interior_angle(tangent1); 07395 07396 //2.create curves to bisection each of the angle passing through the 07397 // vertices of the triangle 07398 CubitVector t_curve11 = 07399 vectorRotate(angle1/2.0, normal1, tangent1); 07400 t_curve11.normalize(); 07401 CubitVector p11 = vt1+t_curve11; 07402 07403 CubitVector t_curve12 = 07404 vectorRotate(90.0 - angle1/2.0, -normal1, tangent1); 07405 t_curve12.normalize(); 07406 CubitVector p12 = vt1 + t_curve12; 07407 07408 CubitVector t_curve21 = 07409 vectorRotate(angle2/2.0, normal2, tangent2); 07410 t_curve21.normalize(); 07411 CubitVector p21 = vt2 + t_curve21; 07412 07413 CubitVector t_curve22 = 07414 vectorRotate(90.0 - angle2/2.0, -normal2, tangent2); 07415 t_curve22.normalize(); 07416 CubitVector p22 = vt2 + t_curve22; 07417 07418 CubitVector t_curve31 = 07419 vectorRotate(angle3/2.0, normal3, tangent3); 07420 t_curve31.normalize(); 07421 07422 CubitVector t_curve32 = 07423 vectorRotate(90.0 - angle3/2.0, -normal3, tangent3); 07424 t_curve32.normalize(); 07425 07426 //3. find the three intersection points which when connected with the vertices, 07427 //intersect at same point. 07428 CubitVector line_p[4], c_p[4], c_ptemp; 07429 double sc, tc; 07430 07431 IntersectionTool int_tool; 07432 for(int i = 0; i < 4; i++) 07433 { 07434 if( i == 0) 07435 { 07436 line_p[0] = vt1; 07437 line_p[1] = p11; 07438 line_p[2] = vt2; 07439 line_p[3] = p21; 07440 } 07441 else if(i == 1) 07442 line_p[3] = p22; 07443 else if(i == 2) 07444 line_p[1] = p12; 07445 else 07446 line_p[3] = p21; 07447 int_tool.closest_points_on_segments(line_p[0], line_p[1], line_p[2], 07448 line_p[3], c_ptemp, c_p[i], sc, tc); 07449 07450 //check if the closeset point from c_p[i] to three curves are on three curves 07451 CubitVector closest1, closest2, closest3; 07452 occ_crv1->closest_point(c_p[i], closest1); 07453 double u = occ_crv1->u_from_position(closest1); 07454 if(u > u11-TOL && u < u12 + TOL) 07455 { 07456 occ_crv2->closest_point(c_p[i], closest2); 07457 u = occ_crv2->u_from_position(closest2); 07458 if(u > u21 - TOL && u < u22 + TOL) 07459 { 07460 occ_crv3->closest_point(c_p[i], closest3); 07461 u = occ_crv3->u_from_position(closest3); 07462 if(u > u31 - TOL && u < u32 + TOL) 07463 { 07464 //4. use the 3 intersection points to find the arc or circle. 07465 OCCPoint occ_p1(closest1); 07466 OCCPoint occ_p2(closest2); 07467 OCCPoint occ_p3(closest3); 07468 return create_arc_three(&occ_p1, &occ_p2, &occ_p3, full, preview); 07469 } 07470 } 07471 } 07472 } 07473 PRINT_ERROR("Can't find the tangent points to create circle.\n"); 07474 return (Curve*) NULL; 07475 } 07476 07477 //=============================================================================== 07478 // Function : create_arc_center_edge 07479 // Member Type: PUBLIC 07480 // Description: 07481 // Author : Jane Hu 07482 // Date : 12/08 07483 //=============================================================================== 07484 Curve* OCCModifyEngine::create_arc_center_edge( TBPoint* pt1, 07485 TBPoint* pt2, 07486 TBPoint* pt3, 07487 const CubitVector& normal, 07488 double radius, 07489 bool full, 07490 bool preview ) 07491 { 07492 CubitVector vec1 = pt1->coordinates(); // Center of arc 07493 CubitVector vec2 = pt2->coordinates(); // Position on arc 07494 CubitVector vec3 = pt3->coordinates(); // Position on arc 07495 07496 CubitVector dir1( vec1, vec2 ); 07497 CubitVector dir2( vec1, vec3 ); 07498 // Re-adjust vec2, vec3 if radius was given 07499 if( radius != CUBIT_DBL_MAX ) 07500 { 07501 CubitVector vec; 07502 vec1.next_point( dir1, radius, vec ); 07503 if(vec.distance_between(vec2) > TOL) 07504 { 07505 vec2 = vec; 07506 pt2 = new OCCPoint(vec); 07507 } 07508 vec1.next_point( dir2, radius, vec ); 07509 if(vec.distance_between(vec3) > TOL) 07510 { 07511 vec3 = vec; 07512 pt3 = new OCCPoint(vec); 07513 } 07514 } 07515 07516 else 07517 { 07518 radius = vec1.distance_between(vec2); 07519 CubitVector vec; 07520 vec1.next_point( dir2, radius, vec ); 07521 if(vec.distance_between(vec3) > TOL) 07522 { 07523 vec3 = vec; 07524 pt3 = new OCCPoint(vec); 07525 } 07526 } 07527 07528 CubitVector normal_dir = normal; 07529 if(normal_dir.length() > TOL) 07530 { 07531 normal_dir.normalize(); 07532 //verify sense 07533 if((dir1 * dir2) % normal_dir < 0.0) 07534 { 07535 TBPoint* p = pt2; 07536 pt2 = pt3; 07537 pt3 = p; 07538 } 07539 else if((dir1 * dir2) % normal_dir == 0.0) 07540 { 07541 PRINT_ERROR("Normal can't be on the plan of the arc.\n"); 07542 return (Curve*) NULL; 07543 } 07544 } 07545 else 07546 { 07547 normal_dir = dir1 * dir2; 07548 normal_dir.normalize(); 07549 } 07550 07551 Handle(Geom_Circle) curve_ptr; 07552 gp_Dir norm(normal_dir.x(), normal_dir.y(), normal_dir.z()); 07553 gp_Pnt center = gp_Pnt( vec1.x(), vec1.y(), vec1.z()); 07554 curve_ptr = GC_MakeCircle(center,norm,radius); 07555 07556 OCCPoint* occ_pt1 = CAST_TO(const_cast<TBPoint*>(pt2),OCCPoint); 07557 TopoDS_Vertex * vt1 = occ_pt1->get_TopoDS_Vertex(); 07558 TopoDS_Edge new_edge; 07559 if(full) 07560 new_edge = BRepBuilderAPI_MakeEdge(curve_ptr, *vt1, *vt1); 07561 07562 else 07563 { 07564 Handle(Geom_TrimmedCurve) arc; 07565 gp_Pnt on_arc1 = gp_Pnt( vec2.x(), vec2.y(), vec2.z()); 07566 gp_Pnt on_arc2 = gp_Pnt( vec3.x(), vec3.y(), vec3.z()); 07567 arc = GC_MakeArcOfCircle(curve_ptr->Circ(), on_arc1, on_arc2, Standard_True); 07568 OCCPoint* occ_pt2 = CAST_TO(const_cast<TBPoint*>(pt3),OCCPoint); 07569 TopoDS_Vertex * vt2 = occ_pt2->get_TopoDS_Vertex(); 07570 new_edge = BRepBuilderAPI_MakeEdge(arc, *vt1, *vt2); 07571 } 07572 07573 if(preview) 07574 { 07575 GfxPreview::clear(); 07576 // Draw this edge 07577 OCCDrawTool::instance()->draw_EDGE( &new_edge, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 07578 return (Curve*) NULL; 07579 } 07580 return OCCQueryEngine::instance()->populate_topology_bridge(new_edge); 07581 } 07582 07583 //=============================================================================== 07584 // Function : create_curve_combine 07585 // Member Type: PUBLIC 07586 // Description: create a curve of combination of several curves. 07587 // Author : Jane Hu 07588 // Date : 03/09 07589 //=============================================================================== 07590 07591 CubitStatus 07592 OCCModifyEngine::create_curve_combine( DLIList<Curve*>& curve_list, 07593 Curve *&new_curve_ptr ) 07594 { 07595 int i; 07596 07597 DLIList<OCCCurve*> occ_curves(curve_list.size()); 07598 CAST_LIST( curve_list, occ_curves, OCCCurve ); 07599 if (curve_list.size() != occ_curves.size()) 07600 { 07601 PRINT_ERROR("In OCCModifyEngine::create_curve_combine\n" 07602 " Not all input curves are OCC Curves.\n"); 07603 return CUBIT_FAILURE; 07604 } 07605 07606 BRepBuilderAPI_MakeWire aWire(*(occ_curves.get_and_step()->get_TopoDS_Edge())); 07607 for(i =1 ; i < curve_list.size(); i++) 07608 { 07609 OCCCurve* curve = occ_curves.get_and_step(); 07610 TopoDS_Edge* edge = curve->get_TopoDS_Edge(); 07611 aWire.Add(*edge); 07612 if(!aWire.IsDone()) 07613 { 07614 PRINT_ERROR("In OCCModifyEngine::create_curve_combine\n" 07615 " The curves are not all connected.\n"); 07616 return CUBIT_FAILURE; 07617 } 07618 } 07619 TopoDS_Wire wire = aWire.Wire(); 07620 BRepAdaptor_CompCurve comp_curve(wire); 07621 GeomAbs_CurveType type = comp_curve.GetType(); 07622 GeomAbs_Shape cont = comp_curve.Continuity(); 07623 if(cont < GeomAbs_G1) 07624 { 07625 PRINT_ERROR("In OCCModifyEngine::create_curve_combine\n" 07626 " The combined curve is not G1 continued.\n"); 07627 return CUBIT_FAILURE; 07628 } 07629 07630 //find the start/end vertices for the combined curve. 07631 double first_u = comp_curve.FirstParameter(); 07632 double last_u = comp_curve.LastParameter(); 07633 gp_Pnt first = comp_curve.Value(first_u); 07634 gp_Pnt last = comp_curve.Value(last_u); 07635 CubitVector first_v(first.X(), first.Y(), first.Z()); 07636 CubitVector last_v(last.X(), last.Y(), last.Z()); 07637 if(first_v.about_equal(last_v)) 07638 comp_curve.SetPeriodic(Standard_True); 07639 07640 DLIList<CubitVector> v_list; 07641 v_list.append(first_v); 07642 v_list.append(last_v); 07643 v_list.reset(); 07644 07645 DLIList<gp_Pnt*> V_list; 07646 for(int j = 0; j < 2; j++) 07647 { 07648 DLIList<TopologyBridge*> children; 07649 if (j == 0) 07650 occ_curves.reset(); 07651 else 07652 occ_curves.last(); 07653 occ_curves.get()->get_children_virt(children); 07654 CubitVector v = v_list.get_and_step(); 07655 for(i = 0 ; i < children.size(); i++) 07656 { 07657 OCCPoint* vertex = CAST_TO(children.get_and_step(), OCCPoint); 07658 CubitVector xyz = vertex->coordinates(); 07659 if(xyz.about_equal(v)) 07660 { 07661 gp_Pnt p ( v.x(), v.y(), v.z()); 07662 V_list.append(&p); 07663 break; 07664 } 07665 } 07666 } 07667 07668 V_list.reset(); 07669 TopoDS_Edge topo_edge; 07670 gp_Lin line; 07671 gp_Circ circle; 07672 gp_Elips ellip; 07673 gp_Hypr hypr; 07674 gp_Parab parab; 07675 Handle_Geom_BezierCurve bezier; 07676 Handle_Geom_BSplineCurve spline; 07677 switch(type) 07678 { 07679 case GeomAbs_Line: 07680 line = comp_curve.Line(); 07681 topo_edge = BRepBuilderAPI_MakeEdge(line,*V_list.get_and_step(), *V_list.get() ); 07682 break; 07683 case GeomAbs_Circle: 07684 circle = comp_curve.Circle(); 07685 topo_edge = BRepBuilderAPI_MakeEdge(circle,*V_list.get_and_step(), *V_list.get() ); 07686 break; 07687 case GeomAbs_Ellipse: 07688 ellip = comp_curve.Ellipse(); 07689 topo_edge = BRepBuilderAPI_MakeEdge(ellip,*V_list.get_and_step(), *V_list.get() ); 07690 break; 07691 case GeomAbs_Hyperbola: 07692 hypr = comp_curve.Hyperbola(); 07693 topo_edge = BRepBuilderAPI_MakeEdge(hypr,*V_list.get_and_step(), *V_list.get() ); 07694 break; 07695 case GeomAbs_Parabola: 07696 parab = comp_curve.Parabola(); 07697 topo_edge = BRepBuilderAPI_MakeEdge(parab,*V_list.get_and_step(), *V_list.get() ); 07698 break; 07699 case GeomAbs_BezierCurve: 07700 bezier = comp_curve.Bezier(); 07701 topo_edge = BRepBuilderAPI_MakeEdge(bezier,*V_list.get_and_step(), *V_list.get() ); 07702 break; 07703 case GeomAbs_BSplineCurve: 07704 spline = comp_curve.BSpline(); 07705 topo_edge = BRepBuilderAPI_MakeEdge(spline,*V_list.get_and_step(), *V_list.get() ); 07706 break; 07707 default: 07708 PRINT_ERROR("In OCCModifyEngine::create_curve_combine\n" 07709 " The combined curve is not G1 continued.\n"); 07710 return CUBIT_FAILURE; 07711 } 07712 TopoDS_Edge *topo_edge_ptr = new TopoDS_Edge(topo_edge); 07713 OCCCurve* occ_c = new OCCCurve(topo_edge_ptr); 07714 new_curve_ptr = occ_c; 07715 return CUBIT_SUCCESS; 07716 } 07717 07718 //=============================================================================== 07719 // Function : get_gqe 07720 // Member Type: PUBLIC 07721 // Description: get the facet geometry query engince instance pointer 07722 // Author : John Fowler 07723 // Date : 10/02 07724 //=============================================================================== 07725 GeometryQueryEngine *OCCModifyEngine::get_gqe() 07726 { 07727 return OCCQueryEngine::instance(); 07728 } 07729 07730 //=============================================================================== 07731 // Function : is_modify_engine 07732 // Member Type: PUBLIC 07733 // Description: return CUBIT_TRUE if the tb_ptr belongs to this modify engine 07734 // Author : John Fowler 07735 // Date : 10/02 07736 //=============================================================================== 07737 CubitBoolean OCCModifyEngine::is_modify_engine(const TopologyBridge *tb_ptr) const 07738 { 07739 return tb_ptr->get_geometry_query_engine() == OCCQueryEngine::instance(); 07740 } 07741 07742 //=============================================================================== 07743 // Function : get_offset_intersections 07744 // Member Type: PUBLIC 07745 // Description: 07746 // Author : Jane Hu 07747 // Date : 03/09 07748 //=============================================================================== 07749 CubitStatus OCCModifyEngine::get_offset_intersections( Curve* curve1, 07750 Curve* curve2, 07751 DLIList<CubitVector>& out_list, 07752 double offset, 07753 CubitBoolean ext_first ) 07754 { 07755 //offset the curve1 in both directions of normal direction of two curves at 07756 //center points. 07757 07758 return CUBIT_SUCCESS; 07759 } 07760 07761 //=============================================================================== 07762 // Function : get_offset_intersections 07763 // Member Type: PUBLIC 07764 // Description: 07765 // Author : Jane Hu 07766 // Date : 03/09 07767 //=============================================================================== 07768 CubitStatus OCCModifyEngine::get_offset_intersections( Curve* curve1, 07769 Surface* face_ptr, 07770 DLIList<CubitVector> & out_list, 07771 double offset, 07772 CubitBoolean ext_surf ) 07773 { 07774 Surface* new_surface = face_ptr; 07775 if(ext_surf) 07776 new_surface = make_Surface(face_ptr, CUBIT_TRUE); 07777 07778 BodySM* bodysm = NULL; 07779 CubitStatus status = CUBIT_SUCCESS; 07780 status = create_offset_surface(new_surface, bodysm, offset); 07781 if(status == CUBIT_FAILURE) 07782 { 07783 PRINT_ERROR("Can't offset surface. \n"); 07784 return status; 07785 } 07786 DLIList<OCCSurface*> surfaces = CAST_TO(bodysm, OCCBody)->my_sheet_surfaces(); 07787 OCCSurface* surface = surfaces.get(); 07788 status = OCCQueryEngine::instance()->get_intersections(curve1, surface, out_list); 07789 07790 if(ext_surf || offset) 07791 OCCQueryEngine::instance()->delete_solid_model_entities(surface); 07792 07793 //offset surface in opposite direction 07794 if(!offset) 07795 return status; 07796 07797 status = create_offset_surface(new_surface, bodysm, -offset); 07798 if(status == CUBIT_FAILURE) 07799 { 07800 PRINT_ERROR("Can't offset surface. \n"); 07801 return status; 07802 } 07803 surfaces.clean_out(); 07804 surfaces = CAST_TO(bodysm, OCCBody)->my_sheet_surfaces(); 07805 surface = surfaces.get(); 07806 status = OCCQueryEngine::instance()->get_intersections(curve1, surface, out_list); 07807 OCCQueryEngine::instance()->delete_solid_model_entities(surface); 07808 if(ext_surf) 07809 OCCQueryEngine::instance()->delete_solid_model_entities(new_surface); 07810 return status; 07811 } 07812 07813 //=============================================================================== 07814 // Function : surface_intersection 07815 // Member Type: PUBLIC 07816 // Description: 07817 // Author : Jane Hu 07818 // Date : 03/09 07819 //=============================================================================== 07820 CubitStatus OCCModifyEngine::surface_intersection( Surface * surface1, 07821 Surface * surface2, 07822 DLIList<Curve*> &intscts, 07823 const double tol) const 07824 { 07825 OCCSurface *occ_surface1 = CAST_TO(surface1, OCCSurface); 07826 if (occ_surface1 == NULL) 07827 { 07828 PRINT_ERROR("Option not supported for non-occ based geometry.\n"); 07829 return CUBIT_FAILURE; 07830 } 07831 07832 OCCSurface *occ_surface2 = CAST_TO(surface2, OCCSurface); 07833 if (occ_surface2 == NULL) 07834 { 07835 PRINT_ERROR("Option not supported for non-occ based geometry.\n"); 07836 return CUBIT_FAILURE; 07837 } 07838 07839 //currently, there's no effect on 'closest' argument or bounded. 07840 BRepExtrema_DistShapeShape distShapeShape(*(occ_surface1->get_TopoDS_Face()), 07841 *(occ_surface2->get_TopoDS_Face())); 07842 07843 //distShapeShape.Perform(); 07844 if (!distShapeShape.IsDone()) 07845 { 07846 PRINT_ERROR("Cannot calculate the intersection points for the input curve and surface.\n"); 07847 return CUBIT_FAILURE; 07848 } 07849 07850 if (distShapeShape.Value() < tol) //intersect 07851 { 07852 int numSol = distShapeShape.NbSolution(); 07853 for (int i = 1; i <= numSol; i++) 07854 { 07855 TopoDS_Shape shape = distShapeShape.SupportOnShape1(i); 07856 if(shape.ShapeType() != TopAbs_EDGE) 07857 continue; 07858 07859 TopoDS_Edge* edge = new TopoDS_Edge(TopoDS::Edge(shape)); 07860 OCCCurve* cv = new OCCCurve(edge); 07861 intscts.append(cv); 07862 } 07863 } 07864 07865 return CUBIT_SUCCESS; 07866 } 07867 07868 //=============================================================================== 07869 // Function : get_3_point_plane 07870 // Member Type: PUBLIC 07871 // Description: 07872 // Author : Jane Hu 07873 // Date : 01/11 07874 //=============================================================================== 07875 CubitStatus OCCModifyEngine::get_3_point_plane( const CubitVector & point_1, 07876 const CubitVector & point_2, 07877 const CubitVector & point_3, 07878 TopoDS_Face*& p_face)const 07879 { 07880 //Calculate normal of the plane 07881 CubitVector v1, v2, normal; 07882 v1 = point_2 - point_1; 07883 v2 = point_3 - point_1; 07884 normal = ~(v1 * v2); 07885 if(fabs(normal.length() - 1) > TOL) 07886 { 07887 PRINT_ERROR("The three points are co-linear, and can't be used as a cutting plane.\n"); 07888 return CUBIT_FAILURE; 07889 } 07890 07891 gp_Pnt pt = gp_Pnt( point_1.x(), point_1.y(), point_1.z()); 07892 gp_Dir normal_dir(normal.x(), normal.y(), normal.z()); 07893 gp_Pln plane(pt, normal_dir); 07894 07895 TopoDS_Face face = BRepBuilderAPI_MakeFace(plane); 07896 p_face = new TopoDS_Face(face); 07897 return CUBIT_SUCCESS; 07898 } 07899 07900 //=============================================================================== 07901 // Function : get_mid_plane 07902 // Member Type: PUBLIC 07903 // Description: 07904 // Author : Jane Hu 07905 // Date : 01/09 07906 //=============================================================================== 07907 CubitStatus OCCModifyEngine::get_mid_plane( const CubitVector & point_1, 07908 const CubitVector & point_2, 07909 const CubitVector & point_3, 07910 BodySM * body_to_trim_to, 07911 BodySM *& result_body ) const 07912 { 07913 //Calculate normal of the mid plane 07914 CubitVector v1, v2, normal; 07915 v1 = point_2 - point_1; 07916 v2 = point_3 - point_1; 07917 normal = ~(v1 * v2); 07918 if(fabs(normal.length() - 1) > TOL) 07919 { 07920 PRINT_ERROR("The three points are co-linear, and can't be used as a cutting plane.\n"); 07921 return CUBIT_FAILURE; 07922 } 07923 07924 gp_Pnt pt = gp_Pnt( point_1.x(), point_1.y(), point_1.z()); 07925 gp_Dir normal_dir(normal.x(), normal.y(), normal.z()); 07926 gp_Pln plane(pt, normal_dir); 07927 07928 TopoDS_Face face = BRepBuilderAPI_MakeFace(plane); 07929 Surface *surf = OCCQueryEngine::instance()->populate_topology_bridge(face, 07930 CUBIT_TRUE); 07931 if(!surf) 07932 { 07933 PRINT_ERROR("Can't create cutting plane.\n"); 07934 return CUBIT_FAILURE; 07935 } 07936 07937 BodySM* tool = CAST_TO(surf, OCCSurface)->my_body(); 07938 DLIList<BodySM*> from_bodies; 07939 from_bodies.append(body_to_trim_to); 07940 DLIList<BodySM*> midplane_bodies; 07941 CubitStatus stat = intersect(tool, from_bodies, midplane_bodies, 07942 CUBIT_TRUE); 07943 OCCQueryEngine::instance()->delete_solid_model_entities(tool); 07944 if (midplane_bodies.size() == 1) 07945 result_body = midplane_bodies.get(); 07946 else { 07947 for (int i = 0; i < midplane_bodies.size(); ++i) 07948 OCCQueryEngine::instance()->delete_solid_model_entities(midplane_bodies.get_and_step()); 07949 stat = CUBIT_FAILURE; 07950 } 07951 return stat; 07952 } 07953 07954 //============================================================================= 07955 // Function : get_spheric_mid_surface 07956 // Member Type: PUBLIC 07957 // Description: Calculates a mid-surface between 2 spheric surfaces. 07958 // Author : Jane Hu 07959 // Date : 01/09 07960 //============================================================================= 07961 CubitStatus OCCModifyEngine::get_spheric_mid_surface( Surface* surface_ptr1, 07962 Surface* surface_ptr2, 07963 BodySM* body_to_trim_to, 07964 BodySM*& result_body ) const 07965 { 07966 OCCSurface* occ_surf1 = CAST_TO(surface_ptr1, OCCSurface); 07967 OCCSurface* occ_surf2 = CAST_TO(surface_ptr2, OCCSurface); 07968 if(occ_surf1->geometry_type() != SPHERE_SURFACE_TYPE || 07969 occ_surf2->geometry_type() != SPHERE_SURFACE_TYPE) 07970 { 07971 PRINT_ERROR( "Both surfaces provided should be sphere type.\n"); 07972 return CUBIT_FAILURE; 07973 } 07974 07975 BRepAdaptor_Surface asurface1(*occ_surf1->get_TopoDS_Face()); 07976 BRepAdaptor_Surface asurface2(*occ_surf2->get_TopoDS_Face()); 07977 07978 gp_Sphere sphere1 = asurface1.Sphere(); 07979 gp_Sphere sphere2 = asurface2.Sphere(); 07980 07981 gp_Pnt center1 = sphere1.Location(); 07982 gp_Pnt center2 = sphere2.Location(); 07983 07984 if(!center1.IsEqual(center2, TOL)) 07985 { 07986 PRINT_ERROR( "Spheres need to have the same center.\n"); 07987 return CUBIT_FAILURE; 07988 } 07989 07990 double radius = sphere1.Radius()/2.0 + sphere2.Radius()/2.0; 07991 BodySM* tool = sphere(radius); 07992 CubitVector center(center1.X(), center1.Y(), center1.Z()); 07993 OCCQueryEngine::instance()->translate(tool, center); 07994 07995 //get the tool surfaces as the tool 07996 DLIList<Surface*> surfaces; 07997 tool->surfaces(surfaces); 07998 assert (surfaces.size() == 1); 07999 tool = make_BodySM(surfaces.get()); 08000 08001 DLIList<BodySM*> from_bodies, midsurface_bodies; 08002 from_bodies.append(body_to_trim_to); 08003 08004 CubitStatus stat = intersect(tool, from_bodies, midsurface_bodies, 08005 CUBIT_TRUE); 08006 OCCQueryEngine::instance()->delete_solid_model_entities(tool); 08007 if (midsurface_bodies.size() == 1) 08008 result_body = midsurface_bodies.get(); 08009 else { 08010 for (int i = 0; i < midsurface_bodies.size(); ++i) 08011 OCCQueryEngine::instance()->delete_solid_model_entities(midsurface_bodies.get_and_step()); 08012 stat = CUBIT_FAILURE; 08013 } 08014 08015 return stat; 08016 } 08017 08018 //============================================================================= 08019 // Function : get_conic_mid_surface 08020 // Member Type: PUBLIC 08021 // Description: Calculates a mid-surface between 2 conic surfaces. 08022 // Author : Jane Hu 08023 // Date : 01/09 08024 //============================================================================= 08025 CubitStatus OCCModifyEngine::get_conic_mid_surface( Surface* surface_ptr1, 08026 Surface* surface_ptr2, 08027 BodySM* body_to_trim_to, 08028 BodySM*& result_body ) const 08029 { 08030 OCCSurface* occ_surf1 = CAST_TO(surface_ptr1, OCCSurface); 08031 OCCSurface* occ_surf2 = CAST_TO(surface_ptr2, OCCSurface); 08032 if(occ_surf1->geometry_type() != CONE_SURFACE_TYPE || 08033 occ_surf2->geometry_type() != CONE_SURFACE_TYPE) 08034 { 08035 PRINT_ERROR( "Both surfaces provided should be conic type.\n"); 08036 return CUBIT_FAILURE; 08037 } 08038 08039 BRepAdaptor_Surface asurface1(*occ_surf1->get_TopoDS_Face()); 08040 BRepAdaptor_Surface asurface2(*occ_surf2->get_TopoDS_Face()); 08041 08042 GeomAbs_SurfaceType type1 = asurface1.GetType(); 08043 GeomAbs_SurfaceType type2 = asurface2.GetType(); 08044 if(type1 != type2) 08045 { 08046 PRINT_ERROR( "Both surfaces provided should be both cylinder or cone type.\n"); 08047 return CUBIT_FAILURE; 08048 } 08049 08050 CubitBox bounding_box = GeometryQueryTool::instance()->model_bounding_box(); 08051 double height = (bounding_box.diagonal()).length(); 08052 OCCBody* body = CAST_TO(body_to_trim_to, OCCBody); 08053 CubitVector centroid; 08054 double volume; 08055 body->mass_properties(centroid, volume); 08056 BodySM* tool; 08057 if(type1 == GeomAbs_Cylinder) 08058 { 08059 gp_Cylinder cyl1 = asurface1.Cylinder(); 08060 gp_Cylinder cyl2 = asurface2.Cylinder(); 08061 gp_Ax1 axis1 = cyl1.Axis(); 08062 gp_Ax1 axis2 = cyl2.Axis(); 08063 if(!axis1.IsCoaxial(axis2, 0.001, TOL)) 08064 { 08065 PRINT_ERROR( "Cylinders need to have the same axis of symmetry.\n"); 08066 return CUBIT_FAILURE; 08067 } 08068 double radius = cyl1.Radius()/2.0 + cyl2.Radius()/2.0; 08069 gp_Ax2 axis; 08070 axis.SetAxis(axis1); 08071 TopoDS_Solid S = BRepPrimAPI_MakeCylinder(axis, radius, height); 08072 08073 Lump* lump = OCCQueryEngine::instance()->populate_topology_bridge(S, 08074 CUBIT_TRUE); 08075 08076 if (lump == NULL) 08077 { 08078 PRINT_ERROR("In OCCModifyEngine::get_conic_mid_surface\n" 08079 " Cannot create a cylinder for given radius.\n"); 08080 return CUBIT_FAILURE; 08081 } 08082 08083 tool = CAST_TO(lump, OCCLump)->get_body(); 08084 double z = centroid.z(); 08085 z -= height/2.0; 08086 centroid.z(z); 08087 OCCQueryEngine::instance()->translate(tool, centroid); 08088 } 08089 08090 else //GeomAbs_Cone 08091 { 08092 gp_Cone cone1 = asurface1.Cone(); 08093 gp_Cone cone2 = asurface2.Cone(); 08094 double angle1 = cone1.SemiAngle(); 08095 double angle2 = cone2.SemiAngle(); 08096 if(fabs(angle1 - angle2) > 0.001) 08097 { 08098 PRINT_ERROR( "Cones do not have the same semi-angle.\n"); 08099 return CUBIT_FAILURE; 08100 } 08101 gp_Ax1 axis1 = cone1.Axis(); 08102 gp_Ax1 axis2 = cone2.Axis(); 08103 if(!axis1.IsCoaxial(axis2, 0.001, TOL)) 08104 { 08105 PRINT_ERROR( "Cones need to have the same axis of symmetry.\n"); 08106 return CUBIT_FAILURE; 08107 } 08108 if(axis1.IsOpposite(axis2, 0.001)) 08109 { 08110 PRINT_ERROR( "Cones need to have the same orientation of axis.\n"); 08111 return CUBIT_FAILURE; 08112 } 08113 double r1 = cone1.RefRadius()/2.0 + cone2.RefRadius()/2.0; 08114 gp_Ax3 axis; 08115 axis.SetAxis(axis1); 08116 gp_Cone cone(axis, angle1, r1); 08117 TopoDS_Face face = BRepBuilderAPI_MakeFace(cone); 08118 Surface* surface = 08119 OCCQueryEngine::instance()->populate_topology_bridge(face, CUBIT_TRUE); 08120 tool = CAST_TO(surface,OCCSurface)->my_body(); 08121 } 08122 DLIList<BodySM*> from_bodies, midsurface_bodies; 08123 from_bodies.append(body_to_trim_to); 08124 08125 CubitStatus stat = intersect(tool, from_bodies, midsurface_bodies, 08126 CUBIT_TRUE); 08127 OCCQueryEngine::instance()->delete_solid_model_entities(tool); 08128 if (midsurface_bodies.size() == 1) 08129 result_body = midsurface_bodies.get(); 08130 else { 08131 for (int i = 0; i < midsurface_bodies.size(); ++i) 08132 OCCQueryEngine::instance()->delete_solid_model_entities(midsurface_bodies.get_and_step()); 08133 stat = CUBIT_FAILURE; 08134 } 08135 08136 return stat; 08137 } 08138 08139 //============================================================================= 08140 // Function : get_toric_mid_surface 08141 // Member Type: PUBLIC 08142 // Description: Calculates a mid-surface between 2 toric surfaces. 08143 // Author : Jane Hu 08144 // Date : 01/09 08145 //============================================================================= 08146 CubitStatus OCCModifyEngine::get_toric_mid_surface( Surface* surface_ptr1, 08147 Surface* surface_ptr2, 08148 BodySM* body_to_trim_to, 08149 BodySM*& result_body ) const 08150 { 08151 OCCSurface* occ_surf1 = CAST_TO(surface_ptr1, OCCSurface); 08152 OCCSurface* occ_surf2 = CAST_TO(surface_ptr2, OCCSurface); 08153 if(occ_surf1->geometry_type() != TORUS_SURFACE_TYPE || 08154 occ_surf2->geometry_type() != TORUS_SURFACE_TYPE) 08155 { 08156 PRINT_ERROR( "Both surfaces provided should be toric type.\n"); 08157 return CUBIT_FAILURE; 08158 } 08159 08160 BRepAdaptor_Surface asurface1(*occ_surf1->get_TopoDS_Face()); 08161 BRepAdaptor_Surface asurface2(*occ_surf2->get_TopoDS_Face()); 08162 08163 gp_Torus torus1 = asurface1.Torus(); 08164 gp_Torus torus2 = asurface2.Torus(); 08165 08166 gp_Pnt center1 = torus1.Location(); 08167 gp_Pnt center2 = torus2.Location(); 08168 08169 if(!center1.IsEqual(center2, TOL)) 08170 { 08171 PRINT_ERROR( "Torii need to have the same center.\n"); 08172 return CUBIT_FAILURE; 08173 } 08174 08175 double major_r1 = torus1.MajorRadius(); 08176 double major_r2 = torus2.MajorRadius(); 08177 if(fabs(major_r1 - major_r2) > TOL) 08178 { 08179 PRINT_ERROR( "Torii need to have the same major radius.\n"); 08180 return CUBIT_FAILURE; 08181 } 08182 08183 gp_Ax1 axis1 = torus1.Axis(); 08184 gp_Ax1 axis2 = torus2.Axis(); 08185 if(!axis1.IsCoaxial(axis2, 0.001, TOL)) 08186 { 08187 PRINT_ERROR( "Torii need to have the same axis of symmetry.\n"); 08188 return CUBIT_FAILURE; 08189 } 08190 08191 double radius = torus1.MinorRadius()/2.0 + torus2.MinorRadius()/2.0; 08192 gp_Ax2 axis; 08193 axis.SetAxis(axis1); 08194 TopoDS_Solid S = BRepPrimAPI_MakeTorus(axis, major_r1, radius); 08195 08196 Lump* lump = OCCQueryEngine::instance()->populate_topology_bridge(S, 08197 CUBIT_TRUE); 08198 08199 if (lump == NULL) 08200 { 08201 PRINT_ERROR("In OCCModifyEngine::get_toric_mid_surface\n" 08202 " Cannot create a torus for given radii.\n"); 08203 return CUBIT_FAILURE; 08204 } 08205 08206 BodySM* tool = CAST_TO(lump, OCCLump)->get_body(); 08207 08208 DLIList<BodySM*> from_bodies, midsurface_bodies; 08209 from_bodies.append(body_to_trim_to); 08210 08211 CubitStatus stat = intersect(tool, from_bodies, midsurface_bodies, 08212 CUBIT_TRUE); 08213 OCCQueryEngine::instance()->delete_solid_model_entities(tool); 08214 if (midsurface_bodies.size() == 1) 08215 result_body = midsurface_bodies.get(); 08216 else { 08217 for (int i = 0; i < midsurface_bodies.size(); ++i) 08218 OCCQueryEngine::instance()->delete_solid_model_entities(midsurface_bodies.get_and_step()); 08219 stat = CUBIT_FAILURE; 08220 } 08221 08222 return stat; 08223 } 08224 08225 //============================================================================= 08226 // Function : tweak_chamfer 08227 // Member Type: PUBLIC 08228 // Description: Chamfer curves on solid bodies. The left and right offsets are 08229 // with respect to the curve direction. If the given right offset 08230 // is negative, the left offset is used. Users can preview to 08231 // clarify the meaning of left and right. 08232 // Author : Jane Hu 08233 // Date : 03/2009 08234 //============================================================================= 08235 CubitStatus OCCModifyEngine::tweak_chamfer( DLIList<Curve*> & curve_list, 08236 double left_offset, 08237 DLIList<BodySM*> & new_bodysm_list, 08238 double right_offset, 08239 CubitBoolean keep_old_body, 08240 CubitBoolean preview ) const 08241 { 08242 CubitStatus stat; 08243 int count = 0; 08244 if(right_offset <= 0.0) 08245 right_offset = left_offset; 08246 08247 for(int i = 0; i < curve_list.size(); i++) 08248 { 08249 BodySM * new_bodysm_ptr = NULL; 08250 stat = tweak_fillet(curve_list.get_and_step(), left_offset, right_offset, 08251 new_bodysm_ptr , keep_old_body, CUBIT_FALSE, CUBIT_FALSE); 08252 if(stat && new_bodysm_ptr) 08253 { 08254 new_bodysm_list.append_unique(new_bodysm_ptr); 08255 count = new_bodysm_list.size(); 08256 } 08257 else 08258 break; 08259 } 08260 08261 if(count == 0) 08262 return CUBIT_FAILURE; 08263 08264 if(preview) 08265 { 08266 GfxPreview::clear(); 08267 for(int i = 0; i < new_bodysm_list.size(); i++) 08268 { 08269 BodySM* new_bodysm = new_bodysm_list.get_and_step(); 08270 TopoDS_Shape* modified_shape; 08271 CAST_TO(new_bodysm, OCCBody)->get_TopoDS_Shape(modified_shape); 08272 TopExp_Explorer Ex; 08273 Ex.Init(*modified_shape, TopAbs_FACE); 08274 for( ; Ex.More(); Ex.Next() ) 08275 { 08276 TopoDS_Face face = TopoDS::Face(Ex.Current()); 08277 // Draw this face 08278 OCCDrawTool::instance()->draw_FACE( &face, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 08279 } 08280 } 08281 OCCQueryEngine::instance()->delete_solid_model_entities(new_bodysm_list); 08282 new_bodysm_list.clean_out(); 08283 } 08284 08285 return CUBIT_SUCCESS; 08286 } 08287 08288 //============================================================================= 08289 // Function : tweak_chamfer 08290 // Member Type: PUBLIC 08291 // Description: Chamfer vertices on solid or sheet bodies. On a solid body 08292 // there can be up to 3 offsets; on a sheet body up to 2 offsets. 08293 // The offsets are in the direction of the supplied edges. If 08294 // multiple vertices are supplied, only one offset value is 08295 // allowed and the edges are not used. 08296 // Author : Jane Hu 08297 // Date : 03/09 08298 //============================================================================= 08299 CubitStatus 08300 OCCModifyEngine::tweak_chamfer( DLIList<TBPoint*> & point_list, 08301 double offset1, 08302 DLIList<BodySM*> & new_bodysm_list, 08303 Curve * edge1, 08304 double offset2, 08305 Curve * edge2, 08306 double offset3, 08307 Curve * edge3, 08308 CubitBoolean keep_old_body, 08309 CubitBoolean preview ) const 08310 { 08311 // Sort out vertices between sheet and solid bodies 08312 DLIList<TBPoint*> solid_points, sheet_points; 08313 DLIList<OCCSurface*> s_list; 08314 DLIList<OCCBody*> bodies; 08315 if( sort_points_by_body_type( point_list, solid_points, sheet_points, 08316 s_list, bodies ) == CUBIT_FAILURE ) 08317 return CUBIT_FAILURE; 08318 08319 if(solid_points.size() > 0 && solid_points.size() != bodies.size()) 08320 { 08321 PRINT_ERROR( "cannot find bodies corresponding to the points.\n" ); 08322 return CUBIT_FAILURE; 08323 } 08324 08325 if(sheet_points.size() > 0 && sheet_points.size() != s_list.size()) 08326 { 08327 PRINT_ERROR( "cannot find surfaces corresponding to the points.\n" ); 08328 return CUBIT_FAILURE; 08329 } 08330 08331 // Do simple forms 08332 if( edge1 == NULL || offset2 <= 0.0 ) 08333 { 08334 if( tweak_chamfer_solid( solid_points, bodies, offset1, new_bodysm_list, 08335 keep_old_body, preview )== CUBIT_FAILURE ) 08336 return CUBIT_FAILURE; 08337 return tweak_fillet_chamfer_sheet( sheet_points, s_list, offset1, 08338 CUBIT_FALSE, new_bodysm_list, keep_old_body, preview ); 08339 } 08340 08341 if( solid_points.size() > 1 || sheet_points.size() > 1 ) 08342 { 08343 PRINT_ERROR( "cannot chamfer multiple vertices with a variable radius.\n" ); 08344 return CUBIT_FAILURE; 08345 } 08346 08347 if( solid_points.size() ) 08348 { 08349 TBPoint *point_ptr = solid_points.get(); 08350 08351 if( tweak_chamfer_solid( point_ptr, bodies.get(), offset1, edge1, 08352 offset2, edge2, offset3, edge3, 08353 new_bodysm_list, keep_old_body, preview ) == CUBIT_FAILURE ) 08354 return CUBIT_FAILURE; 08355 08356 return CUBIT_SUCCESS; 08357 } 08358 08359 if( sheet_points.size() ) 08360 { 08361 TBPoint *point_ptr = sheet_points.get(); 08362 08363 if( tweak_chamfer_sheet( point_ptr, s_list.get(), offset1, edge1, offset2, 08364 edge2, new_bodysm_list, keep_old_body, preview ) == CUBIT_FAILURE ) 08365 return CUBIT_FAILURE; 08366 08367 return CUBIT_SUCCESS; 08368 } 08369 return CUBIT_SUCCESS; 08370 } 08371 08372 CubitStatus 08373 OCCModifyEngine::tweak_chamfer_solid( DLIList<TBPoint*> &point_list, 08374 DLIList<OCCBody*> &bodies, 08375 double radius, 08376 DLIList<BodySM*> &new_bodysm_list, 08377 CubitBoolean keep_old_body, 08378 CubitBoolean preview )const 08379 { 08380 //if point_list.size() > 1, after the first chamfer operation, the rest of 08381 //the points in point_list maybe deleted and recreated, so can't use the 08382 //points' pointers any more. 08383 DLIList<CubitVector> p_locs; 08384 if(point_list.size() > 1) 08385 { 08386 for (int i = 1; i < point_list.size(); i++) 08387 p_locs.append(point_list[i]->coordinates()); 08388 } 08389 for(int i = 0; i < point_list.size(); i++) 08390 { 08391 DLIList<TopologyBridge*> parents; 08392 TBPoint* point = point_list.get_and_step(); 08393 OCCBody* body = bodies.get_and_step(); 08394 DLIList<OCCPoint*> new_p_list; 08395 if( i > 0) 08396 { 08397 body->get_all_points(new_p_list); 08398 if(!new_p_list.move_to((OCCPoint*)point)) 08399 { 08400 CubitVector p_loc = p_locs[i-1]; 08401 for(int j = 0; j < new_p_list.size(); j++) 08402 { 08403 CubitVector test_loc = new_p_list.step_and_get()->coordinates(); 08404 if(test_loc == p_loc) 08405 { 08406 point = new_p_list.get(); 08407 break; 08408 } 08409 } 08410 } 08411 } 08412 OCCPoint* occ_point = CAST_TO(point, OCCPoint); 08413 if(occ_point != NULL) 08414 occ_point->get_parents_virt(parents); //OCCCurves 08415 assert(parents.size() == 3); 08416 DLIList<Curve*> curves; 08417 for(int j = 0; j < 3; j++) 08418 { 08419 OCCCurve* occ_curve = CAST_TO(parents.get_and_step(), OCCCurve); 08420 curves.append(occ_curve); 08421 } 08422 CubitStatus stat; 08423 stat = tweak_chamfer_solid(point, body,radius, curves.pop(), radius, 08424 curves.pop(), radius, curves.pop(), new_bodysm_list, 08425 keep_old_body, CUBIT_FALSE ); 08426 if(!stat) 08427 return CUBIT_FAILURE; 08428 } 08429 if(preview) 08430 { 08431 GfxPreview::clear(); 08432 for(int i = 0; i < new_bodysm_list.size(); i++) 08433 { 08434 BodySM* new_bodysm = new_bodysm_list.get_and_step(); 08435 TopoDS_Shape* modified_shape ; 08436 CAST_TO(new_bodysm, OCCBody)->get_TopoDS_Shape(modified_shape); 08437 TopExp_Explorer Ex; 08438 Ex.Init(*modified_shape, TopAbs_FACE); 08439 for( ; Ex.More(); Ex.Next() ) 08440 { 08441 TopoDS_Face face = TopoDS::Face(Ex.Current()); 08442 // Draw this face 08443 OCCDrawTool::instance()->draw_FACE( &face, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 08444 } 08445 } 08446 OCCQueryEngine::instance()->delete_solid_model_entities(new_bodysm_list); 08447 new_bodysm_list.clean_out(); 08448 } 08449 08450 return CUBIT_SUCCESS; 08451 08452 } 08453 08454 CubitStatus 08455 OCCModifyEngine::tweak_chamfer_solid( TBPoint* point_ptr, 08456 OCCBody* body, 08457 double r1, 08458 Curve *c1, 08459 double r2, 08460 Curve *c2, 08461 double r3, 08462 Curve *c3, 08463 DLIList<BodySM *> &new_bodysm_list, 08464 CubitBoolean keep_old_body, 08465 CubitBoolean preview )const 08466 { 08467 if(r1 <= 0.0 || r2 <= 0.0 || r3 <= 0.0) 08468 { 08469 PRINT_ERROR( "Chamfer radii must be greater than zero.\n" ); 08470 return CUBIT_FAILURE; 08471 } 08472 08473 DLIList<Curve*> curves; 08474 curves.append(c1); 08475 curves.append(c2); 08476 curves.append(c3); 08477 08478 DLIList<double> radii; 08479 radii.append(r1); 08480 radii.append(r2); 08481 radii.append(r3); 08482 08483 //check point on curves 08484 OCCPoint* occ_point = CAST_TO(point_ptr, OCCPoint); 08485 CubitVector position = occ_point->coordinates(); 08486 DLIList<CubitVector> locations; 08487 for(int i = 0; i < 3; i++) 08488 { 08489 OCCCurve *occ_curve = NULL; 08490 occ_curve = CAST_TO(curves.get_and_step(), OCCCurve); 08491 double length = occ_curve->measure(); 08492 08493 DLIList<OCCPoint*> point_list; 08494 occ_curve->get_points(point_list); 08495 CubitBoolean in = point_list.is_in_list(occ_point); 08496 if(!in) 08497 { 08498 PRINT_ERROR( "Point is not on curve.\n" ); 08499 return CUBIT_FAILURE; 08500 } 08501 //find cutting points on curves 08502 double u, u1, u2; 08503 occ_curve->get_param_range(u1,u2); 08504 u = occ_curve->u_from_position(position); 08505 if(fabs(u-u1) < TOL) 08506 u = occ_curve->u_from_arc_length(u1, radii[i]); 08507 else 08508 u = occ_curve->u_from_arc_length(u1, length-radii[i]); 08509 CubitVector c_p; 08510 occ_curve->position_from_u(u, c_p); 08511 locations.append(c_p); 08512 } 08513 08514 //decide normal 08515 CubitVector v1, v2, normal; 08516 CubitVector point_1 = locations.pop(); 08517 CubitVector point_2 = locations.pop(); 08518 CubitVector point_3 = locations.pop(); 08519 v1 = point_2 - point_1; 08520 v2 = point_1 - point_3; 08521 normal = ~(v1 * v2); 08522 CubitVector center; 08523 double volume; 08524 body->mass_properties(center, volume); 08525 CubitVector dir = ~(center - position); 08526 if(normal % dir > 0.0)//1, 3, 2 order 08527 { 08528 CubitVector v = point_2; 08529 point_2 = point_3; 08530 point_3 = v; 08531 } 08532 08533 DLIList<BodySM*> bodies; 08534 BodySM* new_body; 08535 if(keep_old_body || preview) 08536 new_body = copy_body(body); 08537 else 08538 new_body = body; 08539 08540 bodies.append(new_body); 08541 const CubitVector p1 = point_1; 08542 const CubitVector p2 = point_2; 08543 const CubitVector p3 = point_3; 08544 CubitStatus status = const_cast<OCCModifyEngine*> (this)-> 08545 section(bodies, p1, p2, p3, 08546 new_bodysm_list, true,false, false); 08547 if(!status) 08548 return CUBIT_FAILURE; 08549 08550 if(!preview) 08551 return CUBIT_SUCCESS; 08552 08553 GfxPreview::clear(); 08554 08555 for(int i = 0; i < new_bodysm_list.size(); i++) 08556 { 08557 BodySM* new_bodysm = new_bodysm_list.get_and_step(); 08558 DLIList<OCCSurface*> surfs = CAST_TO(new_bodysm, OCCBody)->my_sheet_surfaces(); 08559 for(int j = 0 ; j < surfs.size(); j++) 08560 { 08561 TopoDS_Face* modified_shape = surfs.get_and_step()->get_TopoDS_Face(); 08562 // Draw this face 08563 OCCDrawTool::instance()->draw_FACE( modified_shape, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 08564 } 08565 } 08566 OCCQueryEngine::instance()->delete_solid_model_entities(new_bodysm_list); 08567 new_bodysm_list.clean_out(); 08568 08569 return CUBIT_SUCCESS; 08570 } 08571 08572 CubitStatus 08573 OCCModifyEngine::sort_points_by_body_type( DLIList<TBPoint*> &point_list, 08574 DLIList<TBPoint*> &solid_points, 08575 DLIList<TBPoint*> &sheet_points, 08576 DLIList<OCCSurface*> &s_list, 08577 DLIList<OCCBody*> &bodies )const 08578 { 08579 for (int i = 0; i < point_list.size(); i++) 08580 { 08581 DLIList<TopologyBridge*> parents; 08582 OCCPoint* point = CAST_TO(point_list.get_and_step(), OCCPoint); 08583 int curve_size = 0; 08584 if(point != NULL) 08585 { 08586 point->get_parents_virt(parents); //OCCCurves 08587 if(parents.size() < 2) 08588 { 08589 PRINT_ERROR( "Vertex found not attached to any surfaces.\n" ); 08590 return CUBIT_FAILURE; 08591 } 08592 else if(parents.size() > 3) 08593 { 08594 PRINT_ERROR( "Vertex found attached to multiple bodies.\n" ); 08595 return CUBIT_FAILURE; 08596 } 08597 curve_size = parents.size(); 08598 } 08599 08600 OCCCurve* occ_curve = CAST_TO(parents.get(), OCCCurve); 08601 parents.clean_out(); 08602 occ_curve->get_parents_virt(parents); //OCCCoEdges 08603 if(parents.size() == 0) 08604 { 08605 PRINT_ERROR( "Vertex found not attached to any surfaces.\n" ); 08606 return CUBIT_FAILURE; 08607 } 08608 OCCCoEdge* coedge = CAST_TO(parents.get(), OCCCoEdge); 08609 parents.clean_out(); 08610 coedge->get_parents_virt(parents); //OCCLoops 08611 assert(parents.size() > 0); 08612 OCCLoop* loop = CAST_TO(parents.get(), OCCLoop); 08613 parents.clean_out(); 08614 loop->get_parents_virt(parents); //OCCSurface 08615 assert(parents.size() > 0); 08616 OCCSurface* s = CAST_TO(parents.get(), OCCSurface); 08617 if(s->my_body() != NULL && curve_size == 2) //sheet body 08618 { 08619 s_list.append(s); 08620 sheet_points.append(point); 08621 } 08622 else if(s->my_body() != NULL && curve_size == 3) //shell body 08623 { 08624 PRINT_ERROR( "Vertex found attached to multiple surfaces but not on bodies.\n" ); 08625 return CUBIT_FAILURE; 08626 } 08627 else 08628 { 08629 solid_points.append(point); 08630 DLIList<OCCBody*> solid_bodies; 08631 s->get_bodies(solid_bodies); 08632 assert(solid_bodies.size() == 1); 08633 bodies += solid_bodies; 08634 } 08635 } 08636 return CUBIT_SUCCESS; 08637 } 08638 //============================================================================= 08639 // Function : tweak_fillet 08640 // Member Type: PUBLIC 08641 // Description: Create a round fillet (or blend) at the given curves on solid 08642 // bodies. 08643 // Author : Jane Hu 08644 // Date : 01/09 08645 //============================================================================= 08646 CubitStatus OCCModifyEngine::tweak_fillet( DLIList<Curve*> & curve_list, 08647 double radius, 08648 DLIList<BodySM*> & new_bodysm_list, 08649 CubitBoolean keep_old_body, 08650 CubitBoolean preview )const 08651 { 08652 CubitStatus stat; 08653 int count = 0; 08654 for(int i = 0; i < curve_list.size(); i++) 08655 { 08656 BodySM * new_bodysm_ptr = NULL; 08657 stat = tweak_fillet(curve_list.get_and_step(), radius, radius, 08658 new_bodysm_ptr , keep_old_body, CUBIT_FALSE); 08659 if(stat && new_bodysm_ptr) 08660 { 08661 new_bodysm_list.append_unique(new_bodysm_ptr); 08662 count = new_bodysm_list.size(); 08663 } 08664 else 08665 break; 08666 } 08667 08668 if(count == 0) 08669 return CUBIT_FAILURE; 08670 08671 if(preview) 08672 { 08673 GfxPreview::clear(); 08674 for(int i = 0; i < new_bodysm_list.size(); i++) 08675 { 08676 BodySM* new_bodysm = new_bodysm_list.get_and_step(); 08677 TopoDS_Shape* modified_shape ; 08678 CAST_TO(new_bodysm, OCCBody)->get_TopoDS_Shape(modified_shape); 08679 TopExp_Explorer Ex; 08680 Ex.Init(*modified_shape, TopAbs_FACE); 08681 for( ; Ex.More(); Ex.Next() ) 08682 { 08683 TopoDS_Face face = TopoDS::Face(Ex.Current()); 08684 // Draw this face 08685 OCCDrawTool::instance()->draw_FACE( &face, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 08686 } 08687 } 08688 OCCQueryEngine::instance()->delete_solid_model_entities(new_bodysm_list); 08689 new_bodysm_list.clean_out(); 08690 } 08691 08692 return CUBIT_SUCCESS; 08693 } 08694 08695 //============================================================================= 08696 // Function : tweak_fillet 08697 // Member Type: PUBLIC 08698 // Description: Create a round fillet (or blend) at the given curves on a solid 08699 // body. The fillet/chamfer has a variable radius from the 08700 // start to the end of the curve. 08701 // Author : Jane Hu 08702 // Date : 01/09 08703 //============================================================================= 08704 CubitStatus OCCModifyEngine::tweak_fillet( Curve * curve_ptr, 08705 double start_radius, 08706 double end_radius, 08707 BodySM *& new_bodysm_ptr, 08708 CubitBoolean keep_old_body, 08709 CubitBoolean preview )const 08710 { 08711 return tweak_fillet(curve_ptr, start_radius, end_radius, new_bodysm_ptr, 08712 keep_old_body, preview, CUBIT_TRUE); 08713 } 08714 08715 //============================================================================= 08716 // Function : tweak_fillet 08717 // Member Type: private 08718 // Description: Create a round fillet (or blend) at the given curves on a solid 08719 // body. The fillet/chamfer has a variable radius from the 08720 // start to the end of the curve. 08721 // Author : Jane Hu 08722 // Date : 01/09 08723 //============================================================================= 08724 CubitStatus OCCModifyEngine::tweak_fillet( Curve * curve_ptr, 08725 double start_radius, 08726 double end_radius, 08727 BodySM *& new_bodysm_ptr, 08728 CubitBoolean keep_old_body, 08729 CubitBoolean preview, 08730 CubitBoolean if_fillet ) const 08731 { 08732 //check if this id is valid 08733 OCCQueryEngine* oqe = OCCQueryEngine::instance(); 08734 DLIList <OCCBody* > *bodies = oqe->BodyList; 08735 DLIList<OCCCurve*> curves; 08736 for(int j = 0; j < bodies->size(); j++) 08737 { 08738 OCCBody* body = bodies->get_and_step(); 08739 body->get_all_curves(curves); 08740 } 08741 08742 bool curve_alive = false; 08743 for(int j = 0; j < curves.size(); j++) 08744 { 08745 if(curve_ptr == curves.get_and_step()) 08746 { 08747 curve_alive = true; 08748 break; 08749 } 08750 } 08751 08752 if(!curve_alive) 08753 { 08754 PRINT_ERROR("This curve is not valid in the current model.\n"); 08755 return CUBIT_FAILURE; 08756 } 08757 08758 OCCCurve *occ_curve = CAST_TO(curve_ptr, OCCCurve); 08759 TopoDS_Edge* topo_edge = occ_curve->get_TopoDS_Edge(); 08760 08761 TopTools_IndexedDataMapOfShapeListOfShape M; 08762 DLIList<TopoDS_Shape*> shape_list; 08763 TopoDS_Face* s = NULL; 08764 for(int j = 0; j < bodies->size(); j++) 08765 { 08766 OCCBody* body = bodies->get_and_step(); 08767 TopExp_Explorer Ex; 08768 TopoDS_Shape* pshape ; 08769 body->get_TopoDS_Shape(pshape); 08770 08771 if (pshape && !pshape->IsNull()) 08772 { 08773 M.Clear(); 08774 TopExp::MapShapesAndAncestors(*pshape, TopAbs_EDGE, TopAbs_COMPOUND, M); 08775 if(!M.Contains(*topo_edge)) 08776 continue; 08777 08778 shape_list.append_unique(pshape); 08779 } 08780 08781 if(!if_fillet) //for chamfer, need to know the face for the curve. 08782 { 08783 DLIList<TopologyBridge*> parents; 08784 occ_curve->get_parents_virt(parents); //OCCCoEdges 08785 assert(parents.size() > 1); 08786 OCCCoEdge* coedge = CAST_TO(parents.get(), OCCCoEdge); 08787 parents.clean_out(); 08788 coedge->get_parents_virt(parents); //OCCLoops 08789 assert(parents.size() > 0); 08790 OCCLoop* loop = CAST_TO(parents.get(), OCCLoop); 08791 parents.clean_out(); 08792 loop->get_parents_virt(parents); //OCCSurface 08793 assert(parents.size() > 0); 08794 s = CAST_TO(parents.get(), OCCSurface)->get_TopoDS_Face(); 08795 } 08796 } 08797 if(shape_list.size() != 1) 08798 { 08799 PRINT_ERROR("Fillets must be created on solids.\n"); 08800 return CUBIT_FAILURE; 08801 } 08802 08803 TopoDS_Shape newShape; 08804 TopoDS_Shape* shape = shape_list.get(); 08805 if(keep_old_body) 08806 { 08807 BRepBuilderAPI_Copy api_copy(*shape); 08808 newShape = api_copy.ModifiedShape(*shape); 08809 } 08810 else 08811 newShape = *shape; 08812 08813 BRepBuilderAPI_MakeShape* fillet; 08814 if(if_fillet) 08815 { 08816 fillet = new BRepFilletAPI_MakeFillet(newShape); 08817 dynamic_cast<BRepFilletAPI_MakeFillet*>(fillet)->Add(start_radius, end_radius, *topo_edge); 08818 } 08819 else 08820 { 08821 fillet = new BRepFilletAPI_MakeChamfer(newShape); 08822 dynamic_cast<BRepFilletAPI_MakeChamfer*>(fillet)->Add(start_radius, end_radius, *topo_edge, *s); 08823 } 08824 fillet->Build(); 08825 08826 if(!fillet->IsDone()) 08827 { 08828 PRINT_ERROR("Can't create fillet on given curve.\n"); 08829 return CUBIT_FAILURE; 08830 } 08831 TopoDS_Shape modified_shape = fillet->Shape(); 08832 08833 if( !preview ) 08834 { 08835 TopExp_Explorer Ex; 08836 Ex.Init(newShape, TopAbs_SOLID); 08837 TopoDS_Solid old_solid = TopoDS::Solid(Ex.Current()); 08838 OCCLump::update_OCC_entity(old_solid , modified_shape, fillet); 08839 DLIList<TopologyBridge*> tbs = OCCQueryEngine::instance()->populate_topology_bridge(modified_shape); 08840 new_bodysm_ptr = CAST_TO(tbs.get(), BodySM); 08841 } 08842 else 08843 { 08844 GfxPreview::clear(); 08845 08846 TopExp_Explorer Ex; 08847 Ex.Init(modified_shape, TopAbs_FACE); 08848 for( ; Ex.More(); Ex.Next() ) 08849 { 08850 TopoDS_Face face = TopoDS::Face(Ex.Current()); 08851 // Draw this face 08852 OCCDrawTool::instance()->draw_FACE( &face, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 08853 } 08854 } 08855 delete fillet; 08856 return CUBIT_SUCCESS; 08857 } 08858 08859 //============================================================================= 08860 // Function : tweak_fillet 08861 // Member Type: PUBLIC 08862 // Description: Create a round fillet (or blend) at the given vertices on sheet 08863 // bodies. 08864 // Author : Jane Hu 08865 // Date : 01/09 08866 //============================================================================= 08867 CubitStatus 08868 OCCModifyEngine::tweak_fillet( DLIList<TBPoint*> & ref_vertex_list, 08869 double radius, 08870 DLIList<BodySM*> & new_bodysm_list, 08871 CubitBoolean keep_old_body, 08872 CubitBoolean preview ) const 08873 { 08874 DLIList<OCCSurface*> s_list; 08875 return tweak_fillet_chamfer_sheet(ref_vertex_list, s_list, radius, CUBIT_TRUE, 08876 new_bodysm_list, keep_old_body, preview); 08877 } 08878 08879 CubitStatus 08880 OCCModifyEngine::tweak_fillet_chamfer_sheet( DLIList<TBPoint*> & ref_vertex_list, 08881 DLIList<OCCSurface*> faces, 08882 double radius, 08883 CubitBoolean is_fillet, 08884 DLIList<BodySM*> & new_bodysm_list, 08885 CubitBoolean keep_old_body, 08886 CubitBoolean preview )const 08887 { 08888 TopTools_IndexedDataMapOfShapeListOfShape M; 08889 08890 for(int i = 0; i < ref_vertex_list.size(); i ++) 08891 { 08892 TBPoint* pnt = ref_vertex_list.get_and_step(); 08893 OCCPoint* occ_pnt = CAST_TO(pnt, OCCPoint); 08894 TopoDS_Vertex* vertex = occ_pnt->get_TopoDS_Vertex(); 08895 OCCSurface* face = NULL; 08896 08897 if( faces.size() == 0) 08898 { 08899 OCCQueryEngine* oqe = OCCQueryEngine::instance(); 08900 //make sure the vertex is on sheet body, not on a volume. 08901 DLIList <OCCBody*> *bodies = oqe->BodyList; 08902 for(int k =0 ; k < bodies->size(); k++) 08903 { 08904 OCCBody* occ_body = bodies->get_and_step(); 08905 TopExp_Explorer Ex; 08906 TopoDS_Shape* pshape ; 08907 occ_body->get_TopoDS_Shape(pshape); 08908 if(pshape && !pshape->IsNull()) 08909 { 08910 M.Clear(); 08911 TopExp::MapShapesAndAncestors(*pshape, TopAbs_VERTEX, TopAbs_COMPOUND, M); 08912 if(M.Contains(*vertex) && !occ_body->is_sheet_body()) 08913 { 08914 PRINT_ERROR("Fillet on vertex can only be done on sheet body.\n"); 08915 return CUBIT_FAILURE; 08916 } 08917 else if(M.Contains(*vertex) && occ_body->is_sheet_body()) 08918 { 08919 DLIList<OCCSurface*> surfaces = occ_body->my_sheet_surfaces(); 08920 face = surfaces.get(); 08921 } 08922 } 08923 } 08924 //find corresponding faces. 08925 if(face == NULL) //in case there's a bug in code. 08926 { 08927 DLIList <OCCSurface* > *surfaces = oqe->SurfaceList; 08928 for(int k =0 ; k < surfaces->size(); k++) 08929 { 08930 OCCSurface* occ_face = surfaces->get_and_step(); 08931 TopoDS_Face* topo_face = occ_face->get_TopoDS_Face(); 08932 TopExp_Explorer Ex; 08933 M.Clear(); 08934 TopExp::MapShapesAndAncestors(*topo_face, TopAbs_VERTEX, TopAbs_FACE, M); 08935 if(!M.Contains(*vertex)) 08936 continue; 08937 face = occ_face; 08938 break; 08939 } 08940 } 08941 } 08942 else 08943 face = faces.get_and_step(); 08944 08945 if(face == NULL) 08946 { 08947 PRINT_ERROR("Can't find corresponding surface for the vertex.\n"); 08948 return CUBIT_FAILURE; 08949 } 08950 08951 if(!is_fillet) 08952 { 08953 //find the two edges sharing the vertex. 08954 DLIList<OCCCurve*> curves; 08955 face->get_curves(curves); 08956 int size = curves.size(); 08957 for(int j = 0; j < size; j ++) 08958 { 08959 DLIList<OCCPoint*> point_list; 08960 OCCCurve *curve = curves.get(); 08961 curve->get_points(point_list); 08962 if(!point_list.is_in_list(occ_pnt)) 08963 curves.remove(); 08964 else 08965 curves.step(); 08966 } 08967 assert (curves.size()==2); 08968 tweak_chamfer_sheet(pnt, face, radius, curves.pop(), radius, curves.pop(), 08969 new_bodysm_list, keep_old_body, CUBIT_FALSE); 08970 } 08971 08972 else 08973 { 08974 TopoDS_Face *shape = face->get_TopoDS_Face(); 08975 TopoDS_Face newShape; 08976 if(keep_old_body) 08977 { 08978 BRepBuilderAPI_Copy api_copy(*shape); 08979 newShape = TopoDS::Face(api_copy.ModifiedShape(*shape)); 08980 } 08981 else 08982 newShape = *shape; 08983 08984 BRepFilletAPI_MakeFillet2d fillet(newShape); 08985 TopoDS_Edge fillet_edge; 08986 fillet_edge = fillet.AddFillet(*vertex, radius); 08987 fillet.Build(); 08988 if(fillet.Status() != ChFi2d_IsDone) 08989 { 08990 PRINT_ERROR("Can't create fillet on given curve.\n"); 08991 return CUBIT_FAILURE; 08992 } 08993 TopoDS_Shape modified_shape = fillet.Shape(); 08994 08995 TopExp_Explorer Ex; 08996 OCCSurface::update_OCC_entity(newShape , modified_shape, &fillet, vertex); 08997 TopoDS_Face modified_face = TopoDS::Face(modified_shape); 08998 Surface* surf = OCCQueryEngine::instance()->populate_topology_bridge(modified_face, CUBIT_TRUE); 08999 BodySM* new_bodysm_ptr = CAST_TO(surf,OCCSurface)->my_body(); 09000 new_bodysm_list.append_unique(new_bodysm_ptr); 09001 } 09002 } 09003 09004 if(!preview ) 09005 return CUBIT_SUCCESS; 09006 09007 GfxPreview::clear(); 09008 09009 for(int i = 0; i < new_bodysm_list.size(); i++) 09010 { 09011 BodySM* new_bodysm = new_bodysm_list.get_and_step(); 09012 DLIList<OCCSurface*> surfs = CAST_TO(new_bodysm, OCCBody)->my_sheet_surfaces(); 09013 for(int j = 0; j < surfs.size(); j ++) 09014 { 09015 TopoDS_Face* modified_shape = surfs.get_and_step()->get_TopoDS_Face(); 09016 // Draw this face 09017 OCCDrawTool::instance()->draw_FACE( modified_shape, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 09018 } 09019 } 09020 OCCQueryEngine::instance()->delete_solid_model_entities(new_bodysm_list); 09021 new_bodysm_list.clean_out(); 09022 09023 return CUBIT_SUCCESS; 09024 } 09025 09026 CubitStatus 09027 OCCModifyEngine::tweak_chamfer_sheet(TBPoint* pnt, 09028 OCCSurface* face, 09029 double d1, 09030 Curve* edge1, 09031 double d2, 09032 Curve* edge2, 09033 DLIList<BodySM*> & new_bodysm_list, 09034 CubitBoolean keep_old_body, 09035 CubitBoolean preview ) const 09036 { 09037 TopoDS_Face *shape = face->get_TopoDS_Face(); 09038 TopoDS_Face newShape; 09039 if(keep_old_body) 09040 { 09041 BRepBuilderAPI_Copy api_copy(*shape); 09042 newShape = TopoDS::Face(api_copy.ModifiedShape(*shape)); 09043 } 09044 else 09045 newShape = *shape; 09046 09047 BRepFilletAPI_MakeFillet2d fillet(newShape); 09048 09049 TopoDS_Edge fillet_edge; 09050 if(edge1 == NULL || edge2 == NULL) 09051 { 09052 PRINT_ERROR("Cannot find the two edges for the vertex.\n"); 09053 return CUBIT_FAILURE; 09054 } 09055 TopoDS_Edge* topo_e1 = CAST_TO(edge1, OCCCurve)->get_TopoDS_Edge(); 09056 TopoDS_Edge* topo_e2 = CAST_TO(edge2, OCCCurve)->get_TopoDS_Edge(); 09057 TopoDS_Vertex common_v; 09058 TopExp::CommonVertex(*topo_e1, *topo_e2, common_v); 09059 fillet_edge = fillet.AddChamfer( *topo_e1, *topo_e2, d1, d2); 09060 09061 fillet.Build() ; 09062 if(fillet.Status() != ChFi2d_IsDone) 09063 { 09064 PRINT_ERROR("Can't create chamfer on given vertex.\n"); 09065 return CUBIT_FAILURE; 09066 } 09067 TopoDS_Shape modified_shape = fillet.Shape(); 09068 09069 if( !preview ) 09070 { 09071 TopExp_Explorer Ex; 09072 Ex.Init(newShape, TopAbs_FACE); 09073 TopoDS_Face old_face = TopoDS::Face(Ex.Current()); 09074 OCCSurface::update_OCC_entity(old_face , modified_shape, &fillet, &common_v); 09075 DLIList<TopologyBridge*> tbs = OCCQueryEngine::instance()->populate_topology_bridge(modified_shape); 09076 BodySM* new_bodysm_ptr = CAST_TO(tbs.get(), BodySM); 09077 new_bodysm_list.append_unique(new_bodysm_ptr); 09078 } 09079 else 09080 { 09081 GfxPreview::clear(); 09082 09083 TopExp_Explorer Ex; 09084 Ex.Init(modified_shape, TopAbs_FACE); 09085 for( ; Ex.More(); Ex.Next() ) 09086 { 09087 TopoDS_Face face = TopoDS::Face(Ex.Current()); 09088 // Draw this face 09089 OCCDrawTool::instance()->draw_FACE( &face, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 09090 } 09091 } 09092 return CUBIT_SUCCESS; 09093 } 09094 //============================================================================= 09095 // Function : tweak_move 09096 // Member Type: PUBLIC 09097 // Description: Tweak specified faces of a volume or volumes along a vector. 09098 // Author : Jane Hu 09099 // Date : 04/09 09100 //============================================================================= 09101 CubitStatus OCCModifyEngine::tweak_move( DLIList<Surface*> & surface_list, 09102 const CubitVector & delta, 09103 DLIList<BodySM*> & new_bodysm_list, 09104 CubitBoolean keep_old_body , 09105 CubitBoolean preview) const 09106 { 09107 CubitStatus stat; 09108 for(int i = 0 ; i < surface_list.size(); i++) 09109 { 09110 Surface* surf = surface_list.get_and_step(); 09111 OCCSurface* occ_surf = CAST_TO(surf, OCCSurface); 09112 if(!occ_surf) 09113 continue; 09114 09115 BodySM* original_body = occ_surf->my_body(); 09116 if(original_body == NULL) 09117 { 09118 DLIList<OCCBody*> original_bodies; 09119 occ_surf->get_bodies(original_bodies); 09120 if(original_bodies.size() > 1) 09121 { 09122 PRINT_ERROR( "Cannot tweak move the surface in non-mainfold solids. \n"); 09123 return CUBIT_FAILURE; 09124 } 09125 else if(original_bodies.size() == 0) 09126 { 09127 PRINT_ERROR( "Interal error: Can't find associated solid. \n"); 09128 return CUBIT_FAILURE; 09129 } 09130 original_body = original_bodies.get(); 09131 assert(original_body != NULL); 09132 } 09133 09134 //check to make sure that the surf is not on a sheet body. 09135 OCCLump* lump = occ_surf->my_lump(); 09136 if(lump != NULL && (lump->my_sheet_surface() || lump->my_shell())) 09137 { 09138 PRINT_ERROR( "Cannot tweak move surfaces that are not in a solid\n"); 09139 return CUBIT_FAILURE; 09140 } 09141 DLIList<GeometryEntity*> ref_ent_list; 09142 ref_ent_list.append(occ_surf); 09143 DLIList<BodySM*> result_bodies; 09144 stat = sweep_translational(ref_ent_list, result_bodies, delta, 0.0, 1, 09145 false, true, false, true); 09146 if(stat == CUBIT_FAILURE) 09147 { 09148 PRINT_ERROR( "Cannot tweak move the surface. \n"); 09149 return CUBIT_FAILURE; 09150 } 09151 assert(result_bodies.size() == 1); 09152 09153 //determine if the delta is to trim the existing body or extend it. 09154 CubitVector center_point; 09155 center_point = occ_surf->center_point(); 09156 center_point += ~delta; 09157 09158 CubitBoolean trim = CUBIT_FALSE; 09159 if(original_body->point_containment(center_point) == CUBIT_PNT_INSIDE) 09160 trim = CUBIT_TRUE; 09161 09162 //subtract or unite the two bodies 09163 if(!trim) 09164 { 09165 result_bodies.insert_first(original_body); 09166 stat = unite(result_bodies, new_bodysm_list, keep_old_body); 09167 } 09168 else 09169 { 09170 DLIList<BodySM*> from_bodies; 09171 from_bodies.append(original_body); 09172 stat = subtract(result_bodies, from_bodies, new_bodysm_list, CUBIT_FALSE, 09173 keep_old_body); 09174 } 09175 if(stat == CUBIT_FAILURE) 09176 return CUBIT_FAILURE; 09177 } 09178 if(preview) 09179 { 09180 GfxPreview::clear(); 09181 for(int i = 0; i < new_bodysm_list.size(); i++) 09182 { 09183 BodySM* new_bodysm = new_bodysm_list.get_and_step(); 09184 TopoDS_Shape* modified_shape ; 09185 CAST_TO(new_bodysm, OCCBody)->get_TopoDS_Shape(modified_shape); 09186 TopExp_Explorer Ex; 09187 Ex.Init(*modified_shape, TopAbs_FACE); 09188 for( ; Ex.More(); Ex.Next() ) 09189 { 09190 TopoDS_Face face = TopoDS::Face(Ex.Current()); 09191 // Draw this face 09192 OCCDrawTool::instance()->draw_FACE( &face, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 09193 } 09194 } 09195 OCCQueryEngine::instance()->delete_solid_model_entities(new_bodysm_list); 09196 new_bodysm_list.clean_out(); 09197 } 09198 return CUBIT_SUCCESS; 09199 } 09200 09201 //============================================================================= 09202 // Function : tweak_move 09203 // Member Type: PUBLIC 09204 // Description: Tweak specified curves of a sheet body along a vector. 09205 // Author : Jane Hu 09206 // Date : 04/09 09207 //============================================================================= 09208 CubitStatus OCCModifyEngine::tweak_move( DLIList<Curve*> & curves, 09209 const CubitVector & delta, 09210 DLIList<BodySM*> & new_bodysm_list, 09211 CubitBoolean keep_old_body, 09212 CubitBoolean preview ) const 09213 { 09214 gp_Dir offset_dir(delta.x(), delta.y(), delta.z()); 09215 double length = delta.length(); 09216 09217 for(int i = 0 ; i < curves.size(); i++) 09218 { 09219 Curve* curve = curves.get_and_step(); 09220 OCCCurve* occ_curve = CAST_TO(curve, OCCCurve); 09221 if(!occ_curve) 09222 continue; 09223 //check to make sure that the curve is on a sheet body. 09224 DLIList<OCCLoop*> loops; 09225 loops = occ_curve->loops(); 09226 if(loops.size() == 0) 09227 { 09228 PRINT_ERROR( "Cannot tweak move curves that are free\n"); 09229 return CUBIT_FAILURE; 09230 } 09231 else if(loops.size() != 1) 09232 { 09233 PRINT_ERROR( "Can only tweak move curves attached to one surface\n"); 09234 return CUBIT_FAILURE; 09235 } 09236 //determine if the delta is to trim the existing surface or extend it. 09237 double u_low, u_upper; 09238 CubitVector a_point; 09239 occ_curve->get_param_range(u_low, u_upper); 09240 occ_curve->position_from_u((u_low + u_upper)/2, a_point); 09241 a_point += ~delta; 09242 DLIList<TopologyBridge*> parents; 09243 loops.get()->get_parents_virt(parents); 09244 OCCSurface* surface = CAST_TO(parents.get(), OCCSurface); 09245 BodySM* original_body = surface->my_body(); 09246 if(!original_body) 09247 original_body = surface->my_shell()->my_body(); 09248 if(!original_body) 09249 { 09250 PRINT_ERROR("Can't tweak move curves on volumes.\n"); 09251 return CUBIT_FAILURE; 09252 } 09253 CubitBoolean trim = CUBIT_FALSE; 09254 if(surface->point_containment(a_point) == CUBIT_PNT_INSIDE) 09255 trim = CUBIT_TRUE; 09256 09257 TopoDS_Edge * edge = occ_curve->get_TopoDS_Edge(); 09258 Standard_Real first; 09259 Standard_Real last; 09260 Handle(Geom_Curve) myCurve = BRep_Tool::Curve(*edge, first, last); 09261 Handle(Geom_SurfaceOfLinearExtrusion) new_surface = 09262 new Geom_SurfaceOfLinearExtrusion(myCurve, offset_dir); 09263 Handle(Geom_RectangularTrimmedSurface) trimmed_surface = 09264 new Geom_RectangularTrimmedSurface(new_surface, first, last, 09265 0, length); 09266 if(trimmed_surface == NULL) 09267 { 09268 PRINT_ERROR( "Can not tweak move the %dth curve\n", i); 09269 return CUBIT_FAILURE; 09270 } 09271 #if OCC_VERSION_MINOR > 5 09272 TopoDS_Face FACE = BRepBuilderAPI_MakeFace(trimmed_surface, TOL); 09273 #else 09274 #if OCC_VERSION_MAINTENANCE < 2 09275 TopoDS_Face FACE = BRepBuilderAPI_MakeFace(trimmed_surface); 09276 #else 09277 TopoDS_Face FACE = BRepBuilderAPI_MakeFace(trimmed_surface, TOL); 09278 #endif 09279 #endif 09280 Surface* extrude_surf= OCCQueryEngine::instance()->populate_topology_bridge(FACE, CUBIT_TRUE); 09281 BodySM* body = CAST_TO(extrude_surf, OCCSurface)->my_body(); 09282 //subtract or unite the two surfaces 09283 DLIList<BodySM*> bodies; 09284 bodies.append(original_body); 09285 CubitStatus stat; 09286 if(!trim) 09287 { 09288 bodies.append(body); 09289 stat = unite(bodies, new_bodysm_list, keep_old_body); 09290 } 09291 else 09292 { 09293 DLIList<BodySM*> tool_bodies; 09294 tool_bodies.append(body); 09295 stat = subtract(tool_bodies, bodies, new_bodysm_list, CUBIT_FALSE, 09296 keep_old_body); 09297 } 09298 if(stat == CUBIT_FAILURE) 09299 return CUBIT_FAILURE; 09300 } 09301 if(preview) 09302 { 09303 GfxPreview::clear(); 09304 for(int i = 0; i < new_bodysm_list.size(); i++) 09305 { 09306 BodySM* new_bodysm = new_bodysm_list.get_and_step(); 09307 TopoDS_Shape* modified_shape ; 09308 CAST_TO(new_bodysm, OCCBody)->get_TopoDS_Shape(modified_shape); 09309 TopExp_Explorer Ex; 09310 Ex.Init(*modified_shape, TopAbs_FACE); 09311 for( ; Ex.More(); Ex.Next() ) 09312 { 09313 TopoDS_Face face = TopoDS::Face(Ex.Current()); 09314 // Draw this face 09315 OCCDrawTool::instance()->draw_FACE( &face, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 09316 } 09317 } 09318 OCCQueryEngine::instance()->delete_solid_model_entities(new_bodysm_list); 09319 new_bodysm_list.clean_out(); 09320 } 09321 return CUBIT_SUCCESS; 09322 } 09323 09324 //============================================================================= 09325 // Function : tweak_offset 09326 // Member Type: PUBLIC 09327 // Description: Tweak specified faces of a volume or volumes by offsetting 09328 // those faces by the offset distance. 09329 // Author : 09330 // Date : 09331 //============================================================================= 09332 CubitStatus OCCModifyEngine::tweak_offset( DLIList<Surface*> & /*surface_list*/, 09333 double /*offset_distance*/, 09334 DLIList<Surface*> *add_surface_list_ptr, 09335 DLIList<double>*, 09336 DLIList<BodySM*> & /*new_bodysm_list*/, 09337 CubitBoolean /*keep_old_body*/, 09338 CubitBoolean show_preview ) const 09339 { 09340 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 09341 return CUBIT_FAILURE; 09342 } 09343 09344 //============================================================================= 09345 // Function : tweak_offset 09346 // Member Type: PUBLIC 09347 // Description: Tweak specified curves of a sheet body or bodies by offsetting 09348 // those curves by the offset distance. 09349 // Author : 09350 // Date : 09351 //============================================================================= 09352 CubitStatus OCCModifyEngine::tweak_offset( DLIList<Curve*> & /*curve_list*/, 09353 double /*offset_distance*/, 09354 DLIList<Curve*>*, 09355 DLIList<double>*, 09356 DLIList<BodySM*> & /*new_bodysm_list*/, 09357 CubitBoolean /*keep_old_body*/, 09358 CubitBoolean show_preview ) const 09359 { 09360 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 09361 return CUBIT_FAILURE; 09362 } 09363 09364 //============================================================================= 09365 // Function : tweak_remove 09366 // Member Type: PUBLIC 09367 // Description: Function to remove surfaces from a body and then extend the 09368 // remaining surfaces to fill the gap or hole. 09369 // Author : 09370 // Date : 09371 //============================================================================= 09372 CubitStatus OCCModifyEngine::tweak_remove( DLIList<Surface*> & /*surface_list*/, 09373 DLIList<BodySM*> & /*new_bodysm_list*/, 09374 CubitBoolean /*extend_adjoining*/, 09375 CubitBoolean /*keep_old_body*/, 09376 CubitBoolean show_preview ) const 09377 { 09378 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 09379 return CUBIT_FAILURE; 09380 } 09381 09382 //============================================================================= 09383 // Function : tweak_remove 09384 // Member Type: PUBLIC 09385 // Description: Function to remove curves from a sheet body and then extend the 09386 // remaining curves or fill the gap or hole. 09387 // Author : 09388 // Date : 09389 //============================================================================= 09390 CubitStatus OCCModifyEngine::tweak_remove( DLIList<Curve*> & /*curve_list*/, 09391 DLIList<BodySM*> & /*new_bodysm_list*/, 09392 CubitBoolean /*keep_old_body*/, 09393 CubitBoolean show_preview ) const 09394 { 09395 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 09396 return CUBIT_FAILURE; 09397 } 09398 09399 //============================================================================= 09400 // Function : tweak_target 09401 // Member Type: PUBLIC 09402 // Description: Tweak specified faces of a volume or volumes up to a target 09403 // surface. 09404 // Author : 09405 // Date : 09406 //============================================================================= 09407 CubitStatus OCCModifyEngine::tweak_target( DLIList<Surface*> & /*surface_list*/, 09408 DLIList<Surface*> & , 09409 DLIList<BodySM*> & /*new_bodysm_list*/, 09410 CubitBoolean extend_flg , 09411 CubitPlane *limit_plane , 09412 CubitBoolean /*reverse_flg*/, 09413 CubitBoolean /*keep_old_body*/, 09414 CubitBoolean show_preview ) const 09415 { 09416 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 09417 return CUBIT_FAILURE; 09418 } 09419 09420 //============================================================================= 09421 // Function : tweak_target 09422 // Member Type: PUBLIC 09423 // Description: Tweak specified edges of a surface or set of surfaces (in sheet 09424 // bodies) up to a target surface. 09425 // Author : 09426 // Date : 09427 //============================================================================= 09428 CubitStatus OCCModifyEngine::tweak_target( DLIList<Curve*> & /*curve_list*/, 09429 DLIList<Surface*> & /*target_surfs*/, 09430 DLIList<BodySM*> & /*new_bodysm_list*/, 09431 CubitBoolean extend_flg , 09432 CubitPlane *limit_plane , 09433 CubitBoolean , 09434 CubitBoolean /*keep_old_body*/, 09435 CubitBoolean show_preview, 09436 double max_area_increase ) const 09437 { 09438 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 09439 return CUBIT_FAILURE; 09440 } 09441 09442 //============================================================================= 09443 // Function : tweak_target 09444 // Member Type: PUBLIC 09445 // Description: Tweak specified edges of a sheet body or bodies up to a target 09446 // curve that is part of a sheet body. The target is a surface 09447 // created by thickening the owning surface of the target curve. 09448 // Author : 09449 // Date : 09450 //============================================================================= 09451 CubitStatus OCCModifyEngine::tweak_target( DLIList<Curve*> & /*curve_list*/, 09452 DLIList<Curve*> & /*target_curve_ptr*/, 09453 DLIList<BodySM*> & /*new_bodysm_list*/, 09454 CubitBoolean extend_flg, 09455 CubitPlane *limit_plane , 09456 CubitBoolean, 09457 CubitBoolean /*keep_old_body*/, 09458 CubitBoolean show_preview, 09459 double max_area_increase ) const 09460 { 09461 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 09462 return CUBIT_FAILURE; 09463 } 09464 09465 CubitStatus OCCModifyEngine::tweak_target( TBPoint *point_ptr, 09466 DLIList<Surface*> &modify_surface_list, 09467 CubitVector &target_loc, 09468 BodySM *&new_bodysm_ptr, 09469 CubitBoolean keep_old_body , 09470 CubitBoolean preview ) const 09471 { 09472 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 09473 return CUBIT_FAILURE; 09474 } 09475 09476 //================================================================================ 09477 // Description: split curve at split_location, upper level geometry gets 09478 // updated as well. 09479 // Author : Jane Hu 09480 // Date : 02/11 09481 //================================================================================ 09482 CubitStatus OCCModifyEngine::split_curve( Curve* curve_to_split, 09483 const CubitVector& split_location, 09484 DLIList<Curve*>& created_curves ) 09485 { 09486 //find if the curve is stand-along or in a body. 09487 OCCQueryEngine* oqe = OCCQueryEngine::instance(); 09488 DLIList <OCCBody* > *bodies = oqe->BodyList; 09489 DLIList<OCCLoop*> *loops = oqe->WireList; 09490 OCCCurve* occ_curve = CAST_TO(curve_to_split, OCCCurve); 09491 TopoDS_Edge* edge = occ_curve->get_TopoDS_Edge(); 09492 09493 LocOpe_SplitShape splitor; 09494 TopoDS_Shape from_shape; 09495 CubitBoolean found = false; 09496 //bodies consists compounds or solids. 09497 for(int i = 0; i < bodies->size(); i ++) 09498 { 09499 OCCBody* body = bodies->get_and_step(); 09500 TopoDS_Shape* topo_shape; 09501 body->get_TopoDS_Shape(topo_shape); 09502 from_shape = *topo_shape; 09503 TopTools_IndexedDataMapOfShapeListOfShape M; 09504 09505 TopExp::MapShapesAndAncestors(from_shape, TopAbs_EDGE, TopAbs_SHAPE, M); 09506 09507 if(M.Contains(*edge) ) 09508 { 09509 found = true; 09510 break; 09511 } 09512 } 09513 09514 for(int i = 0 ; found == false && i < loops->size(); i++) 09515 { 09516 OCCLoop* loop = loops->get_and_step(); 09517 TopoDS_Wire* topo_loop = loop->get_TopoDS_Wire(); 09518 from_shape = *topo_loop; 09519 TopTools_IndexedDataMapOfShapeListOfShape M; 09520 TopExp::MapShapesAndAncestors(from_shape, TopAbs_EDGE, TopAbs_WIRE, M); 09521 if(M.Contains(*edge)) 09522 { 09523 found = true; 09524 break; 09525 } 09526 } 09527 09528 if(!found) 09529 from_shape = *edge; 09530 09531 TopoDS_Shape* p_shape = &from_shape; 09532 CubitStatus status = split_shape_by_location(p_shape, curve_to_split, 09533 split_location, created_curves); 09534 09535 DLIList<TopoDS_Shape*> shape_list; 09536 DLIList<BodySM*> new_body_list; 09537 shape_list.append(p_shape); 09538 shape_to_bodySM(shape_list, new_body_list); 09539 return status; 09540 } 09541 09542 //================================================================================ 09543 // Function : split_shape_by_location 09544 // Description: split curve at split_location, upper level geometry (from_shape) 09545 // gets updated as well. 09546 // Author : Jane Hu 09547 // Date : 02/11 09548 //================================================================================ 09549 CubitStatus OCCModifyEngine::split_shape_by_location(TopoDS_Shape *&from_shape, 09550 Curve* curve_to_split, 09551 const CubitVector& split_location, 09552 DLIList<Curve*>& created_curves)const 09553 { 09554 LocOpe_SplitShape splitor(*from_shape); 09555 CubitBoolean is_edge = (from_shape->ShapeType() == TopAbs_EDGE); 09556 TopoDS_Edge edge = *CAST_TO(curve_to_split, OCCCurve)->get_TopoDS_Edge(); 09557 gp_Pnt pt = gp_Pnt(split_location.x(), split_location.y(), split_location.z()); 09558 TopoDS_Vertex vertex = BRepBuilderAPI_MakeVertex(pt); 09559 double param = curve_to_split->u_from_position(split_location); 09560 //double check that the split location is in curve 09561 double u_max, u_min; 09562 curve_to_split->get_param_range(u_min, u_max); 09563 if( param >= u_max || param <= u_min) 09564 return CUBIT_SUCCESS; 09565 09566 splitor.Add(vertex, param, edge); 09567 09568 //update the curve_list 09569 TopTools_ListOfShape edge_shapes; 09570 edge_shapes.Assign(splitor.DescendantShapes(edge)); 09571 while(edge_shapes.Extent()) 09572 { 09573 TopoDS_Shape edge_shape = edge_shapes.First(); 09574 TopoDS_Edge occ_edge = TopoDS::Edge(edge_shape); 09575 OCCCurve* test_curve; 09576 if(!OCCQueryEngine::instance()->OCCMap->IsBound(occ_edge)) 09577 { 09578 if(is_edge) 09579 test_curve = CAST_TO(OCCQueryEngine::instance()->populate_topology_bridge(occ_edge, CUBIT_TRUE), OCCCurve); 09580 else 09581 test_curve = CAST_TO(OCCQueryEngine::instance()->populate_topology_bridge(occ_edge), OCCCurve); 09582 DLIList<OCCPoint*> points; 09583 test_curve->get_points(points); 09584 for(int i = 0 ; i < points.size(); i++) 09585 points.get_and_step()->remove_curve(test_curve); 09586 } 09587 else 09588 test_curve = CAST_TO(OCCQueryEngine::instance()->populate_topology_bridge(occ_edge), OCCCurve); 09589 09590 if(test_curve) 09591 { 09592 created_curves.append_unique(test_curve); 09593 //remove the points' curvelist of curve_to_split 09594 DLIList<OCCPoint*> points; 09595 test_curve->get_points(points); 09596 for(int i = 0; i < points.size(); i++) 09597 { 09598 OCCPoint* occ_p = points.get_and_step(); 09599 occ_p->remove_curve(CAST_TO(curve_to_split, OCCCurve)); 09600 if(from_shape->ShapeType() > TopAbs_EDGE) 09601 occ_p->remove_curve(test_curve); 09602 } 09603 } 09604 edge_shapes.RemoveFirst(); 09605 } 09606 09607 TopTools_ListOfShape shapes; 09608 shapes.Assign(splitor.DescendantShapes(*from_shape)); 09609 if(from_shape->ShapeType() ==TopAbs_COMPOUND) 09610 OCCBody::update_OCC_entity(*from_shape, shapes.First(), 09611 (BRepBuilderAPI_MakeShape*) NULL, &splitor); 09612 09613 else if(shapes.First().ShapeType() == TopAbs_SOLID) 09614 OCCLump::update_OCC_entity(TopoDS::Solid(*from_shape), 09615 shapes.First(), (BRepBuilderAPI_MakeShape*) NULL, &splitor); 09616 09617 else if(shapes.First().ShapeType() == TopAbs_SHELL) 09618 OCCShell::update_OCC_entity(TopoDS::Shell(*from_shape), 09619 shapes.First(), (BRepBuilderAPI_MakeShape*) NULL, &splitor); 09620 09621 else if(shapes.First().ShapeType() == TopAbs_FACE) 09622 OCCSurface::update_OCC_entity(TopoDS::Face(*from_shape), 09623 shapes.First(), (BRepBuilderAPI_MakeShape*) NULL, NULL, &splitor); 09624 09625 else if(shapes.First().ShapeType() == TopAbs_WIRE) 09626 OCCLoop::update_OCC_entity(TopoDS::Wire(*from_shape), &splitor); 09627 09628 from_shape = new TopoDS_Shape(shapes.First()); 09629 return CUBIT_SUCCESS; 09630 } 09631 09632 CubitStatus OCCModifyEngine::remove_curve_slivers( BodySM* body, 09633 double lengthlimit ) const 09634 { 09635 DLIList<CubitBoolean> is_volume; 09636 DLIList<BodySM*> bodies; 09637 DLIList<TopoDS_Shape*> shapes; 09638 bodies.append(body); 09639 CubitStatus status = get_shape_list(bodies, shapes, is_volume, CUBIT_FALSE); 09640 if(!status) 09641 { 09642 PRINT_ERROR("Can't find underlying TopoDS_Shape for this body.\n"); 09643 return CUBIT_FAILURE; 09644 } 09645 Handle(ShapeBuild_ReShape) context; 09646 TopoDS_Shape new_shape = ShapeFix::RemoveSmallEdges(*shapes.get(), 09647 lengthlimit, context); 09648 new_shape = context->Apply(new_shape, TopAbs_COMPOUND); 09649 if(context->Status(ShapeExtend_OK)) 09650 { 09651 PRINT_INFO("There's no small edges on this body.\n"); 09652 return CUBIT_SUCCESS; 09653 } 09654 09655 else if(context->Status(ShapeExtend_FAIL)) 09656 { 09657 PRINT_ERROR("Small edges can't be removed from this body.\n"); 09658 return CUBIT_FAILURE; 09659 } 09660 09661 OCCQueryEngine::instance()->delete_solid_model_entities(body); 09662 DLIList<TopologyBridge*>tbs = OCCQueryEngine::instance()->populate_topology_bridge(new_shape); 09663 09664 return CUBIT_SUCCESS; 09665 } 09666 09667 //================================================================================ 09668 // Description: Creates a net surface. 09669 // Author : Tyronne Lim 09670 // Date : 08/18/03 09671 //================================================================================ 09672 CubitStatus OCCModifyEngine::create_net_surface( DLIList<Surface*>& /*ref_face_list*/, 09673 BodySM *& /*new_body*/, 09674 DLIList<DLIList<CubitVector*>*> & /*vec_lists_u*/, 09675 DLIList<DLIList<CubitVector*>*> & /*vec_lists_v*/, 09676 double /*net_tol*/, 09677 CubitBoolean /*heal*/ ) const 09678 { 09679 PRINT_ERROR("Function not implemented in this engine.\n"); 09680 return CUBIT_FAILURE; 09681 } 09682 09683 //================================================================================ 09684 // Description: Creates a net surface. 09685 // Author : Tyronne Lim 09686 // Date : 08/18/03 09687 //================================================================================ 09688 CubitStatus OCCModifyEngine::create_net_surface( DLIList<Curve*>& /*u_curves*/, 09689 DLIList<Curve*>& /*v_curves*/, 09690 BodySM *& /*new_body*/, 09691 double /*net_tol*/, 09692 CubitBoolean /*heal*/ ) const 09693 { 09694 PRINT_ERROR("Function not implemented in this engine.\n"); 09695 return CUBIT_FAILURE; 09696 } 09697 09698 //================================================================================ 09699 // Description: Creates an offset surface. 09700 // Author : Jane Hu 09701 // Date : 01/09 09702 //================================================================================ 09703 CubitStatus OCCModifyEngine::create_offset_surface( Surface* face_ptr, 09704 BodySM*& new_body, 09705 double offset ) const 09706 { 09707 //create offset surface from its center along center normal of distance 09708 //"offset" 09709 OCCSurface *occ_surface = CAST_TO(face_ptr, OCCSurface); 09710 if (occ_surface == NULL) 09711 { 09712 PRINT_ERROR("Option not supported for non-occ based geometry.\n"); 09713 return CUBIT_FAILURE; 09714 } 09715 09716 Surface* c_surface = NULL; 09717 c_surface = make_Surface(occ_surface); 09718 if (c_surface == NULL) 09719 { 09720 PRINT_ERROR("Cannot copy surface in sweep_translational.\n"); 09721 return CUBIT_FAILURE; 09722 } 09723 occ_surface = CAST_TO(c_surface, OCCSurface); 09724 09725 CubitVector center = occ_surface->center_point(); 09726 CubitVector normal; 09727 occ_surface->closest_point(center,NULL,&normal); 09728 CubitVector v = normal * offset; 09729 OCCQueryEngine::instance()->translate(occ_surface, v); 09730 new_body = occ_surface->my_body(); 09731 return CUBIT_SUCCESS; 09732 } 09733 09734 //================================================================================ 09735 // Description: Creates an offset body. 09736 // Author : Jane Hu 09737 // Date : 01/09 09738 //================================================================================ 09739 CubitStatus OCCModifyEngine::create_offset_body( BodySM* body_ptr, 09740 BodySM*& new_bodysm, 09741 double offset_distance ) const 09742 { 09743 PRINT_ERROR("Function not implemented because offset_distance \n" 09744 "doesn't show offset direction.\n"); 09745 return CUBIT_FAILURE; 09746 } 09747 09748 //================================================================================ 09749 // Description: Creates a skin surface. 09750 // Author : Jane Hu 09751 // Date : 01/09 09752 //================================================================================ 09753 CubitStatus OCCModifyEngine::create_skin_surface( DLIList<Curve*>& curves, 09754 BodySM*& new_body, 09755 DLIList<Curve*>&) const 09756 { 09757 new_body = NULL; 09758 Surface* surf = make_Surface(BEST_FIT_SURFACE_TYPE, curves); 09759 if(surf) 09760 { 09761 new_body = CAST_TO(surf, OCCSurface)->my_body(); 09762 return CUBIT_SUCCESS; 09763 } 09764 return CUBIT_FAILURE; 09765 } 09766 09767 //================================================================================ 09768 // Description: Creates a shell body from lofting surfaces. 09769 // Author : Jane Hu 09770 // Date : 01/09 09771 //================================================================================ 09772 //CubitStatus OCCModifyEngine::loft_surfaces( Surface * face1, 09773 // const double & /*takeoff1*/, 09774 // Surface * face2, 09775 // const double & /*takeoff2*/, 09776 // BodySM*& new_body, 09777 // CubitBoolean /*arc_length_option*/, 09778 // CubitBoolean /*twist_option*/, 09779 // CubitBoolean /*align_direction*/, 09780 // CubitBoolean /*perpendicular*/, 09781 // CubitBoolean /*simplify_option*/ ) const 09782 //{ 09783 // BRepOffsetAPI_ThruSections loft(CUBIT_FALSE); 09784 // CubitStatus stat = do_loft(loft, face1, face2); 09785 // if(!stat) 09786 // return CUBIT_FAILURE; 09787 // 09788 // TopoDS_Shape shape = loft.Shape(); 09789 // TopoDS_Shell shell = TopoDS::Shell(shape); 09790 // OCCShell* occ_shell = OCCQueryEngine::instance()->populate_topology_bridge(shell, CUBIT_TRUE); 09791 // if (occ_shell == NULL) 09792 // { 09793 // PRINT_ERROR("In OCCModifyEngine::loft_surfaces\n" 09794 // " Cannot create a loft surface for given surfaces.\n"); 09795 // return CUBIT_FAILURE; 09796 // } 09797 // new_body = occ_shell->my_body(); 09798 // return CUBIT_SUCCESS; 09799 //} 09800 09801 //================================================================================ 09802 // Description: Creates a solid body by lofting surfaces between surfaces 09803 // Author : Jane Hu 09804 // Date : 02/12 09805 //================================================================================ 09806 CubitStatus OCCModifyEngine::loft_surfaces_to_body( DLIList<Surface*> &surfaces, 09807 DLIList<double> &takeoff_factor_list, //not used 09808 DLIList<Surface*> &takeoff_vector_surface_list, //not used 09809 DLIList<CubitVector> &surface_takeoff_vector_list, //not used 09810 DLIList<Curve*> &takeoff_vector_curve_list, //not used 09811 DLIList<CubitVector> &curve_takeoff_vector_list, //not used 09812 DLIList<Curve*> &guides, 09813 DLIList<TBPoint*> &match_vertices_list, //not used 09814 BodySM*& new_body, 09815 CubitBoolean global_guides, 09816 CubitBoolean closed, //not used 09817 CubitBoolean show_matching_curves, 09818 CubitBoolean preview)const 09819 { 09820 BRepOffsetAPI_ThruSections loft(CUBIT_TRUE); 09821 if(global_guides || guides.size() > 0) 09822 loft.Init(CUBIT_TRUE, CUBIT_TRUE); 09823 else 09824 loft.SetSmoothing(CUBIT_TRUE); 09825 CubitStatus stat = do_loft(loft, surfaces) ; 09826 if(!stat) 09827 return CUBIT_FAILURE; 09828 09829 TopoDS_Shape shape = loft.Shape(); 09830 if(preview && show_matching_curves) 09831 { 09832 PRINT_WARNING("Can't show matching curves in OCC.\n"); 09833 } 09834 else if(preview) 09835 { 09836 GfxPreview::clear(); 09837 // Draw this topoDS_shape 09838 OCCDrawTool::instance()->draw_TopoDS_Shape( &shape, CUBIT_BLUE_INDEX, CUBIT_FALSE, CUBIT_TRUE ); 09839 09840 return CUBIT_SUCCESS; 09841 } 09842 TopoDS_Solid solid = TopoDS::Solid(shape); 09843 Lump* lump = OCCQueryEngine::instance()->populate_topology_bridge(solid, CUBIT_TRUE); 09844 if (lump == NULL) 09845 { 09846 PRINT_ERROR("In OCCModifyEngine::loft_surfaces_to_body\n" 09847 " Cannot create a loft body for given surfaces.\n"); 09848 return CUBIT_FAILURE; 09849 } 09850 new_body = CAST_TO(lump, OCCLump)->get_body(); 09851 return CUBIT_SUCCESS; 09852 } 09853 09854 CubitStatus OCCModifyEngine::do_loft(BRepOffsetAPI_ThruSections& loft, 09855 DLIList<Surface*> &surfaces) const 09856 { 09857 for(int i = 0; i < surfaces.size(); i++) 09858 { 09859 OCCSurface* surf = CAST_TO(surfaces.get_and_step(), OCCSurface); 09860 if(!surf) 09861 { 09862 PRINT_ERROR("Surfaces are not OCC type.\n"); 09863 return CUBIT_FAILURE; 09864 } 09865 TopoDS_Face* topo_face = surf->get_TopoDS_Face(); 09866 TopExp_Explorer Ex; 09867 Ex.Init(*topo_face, TopAbs_WIRE); 09868 TopoDS_Wire wire = TopoDS::Wire(Ex.Current()); 09869 if(Ex.More()) 09870 { 09871 Ex.Next(); 09872 if(Ex.Current().ShapeType() == TopAbs_WIRE) 09873 { 09874 PRINT_ERROR("Surface must have only one loop.\n"); 09875 return CUBIT_FAILURE; 09876 } 09877 } 09878 loft.AddWire(wire); 09879 } 09880 loft.Build(); 09881 if(!loft.IsDone()) 09882 { 09883 PRINT_ERROR("Surfaces can't be loft into a body.\n"); 09884 return CUBIT_FAILURE; 09885 } 09886 return CUBIT_SUCCESS; 09887 } 09888 09889 //================================================================================ 09890 // Description: Creates a surface using a list of vectors, project to surface if 09891 // given. Those points are connected into a closed wire and then 09892 // a surface is created on it. 09893 // Author : Jane Hu 09894 // Date : 02/11 09895 //================================================================================ 09896 CubitStatus OCCModifyEngine::create_surface( DLIList<CubitVector*>& vec_list, 09897 BodySM *& new_body, 09898 Surface * surface_ptr, 09899 CubitBoolean project_points) const 09900 { 09901 int i; 09902 CubitStatus stat; 09903 DLIList<TBPoint*> new_points; 09904 DLIList<CubitVector*> new_vec_list; 09905 if (surface_ptr) 09906 { 09907 // Check the project_points option and do the necessary checks or projections. 09908 if (project_points) 09909 { 09910 // Create a new list of points that are projected to the surface 09911 vec_list.reset(); 09912 CubitVector *vec_ptr, new_vec; 09913 for( i=0; i<vec_list.size(); i++ ) 09914 { 09915 vec_ptr = vec_list.get_and_step(); 09916 stat = surface_ptr->closest_point( *vec_ptr, &new_vec ); 09917 if(stat) 09918 new_vec_list.append(new CubitVector(new_vec) ); 09919 else 09920 { 09921 PRINT_ERROR("Can't project the %dth point onto surface \n", i+1); 09922 for (int j = 0; j < new_vec_list.size(); j++) 09923 delete new_vec_list.get_and_step(); 09924 return CUBIT_FAILURE; 09925 } 09926 } 09927 } 09928 09929 else 09930 { 09931 // Make sure the points lie on the surface 09932 vec_list.reset(); 09933 CubitVector loc_on_surf; 09934 CubitVector *vec_ptr; 09935 for( i=0; i<vec_list.size(); i++ ) 09936 { 09937 vec_ptr = vec_list.get_and_step(); 09938 surface_ptr->closest_point( *vec_ptr, &loc_on_surf ); 09939 09940 if (!vec_ptr->within_tolerance(loc_on_surf, GEOMETRY_RESABS)) 09941 { 09942 PRINT_ERROR("all locations must lie on Surface\n" ); 09943 return CUBIT_FAILURE; 09944 } 09945 } 09946 new_vec_list = vec_list; 09947 } 09948 } 09949 09950 // Make the surface in the solid modeller 09951 else 09952 new_vec_list = vec_list; 09953 09954 for( i=0; i<new_vec_list.size(); i++ ) 09955 { 09956 CubitVector* vec_ptr = new_vec_list.get_and_step(); 09957 OCCPoint* point = new OCCPoint(*vec_ptr); 09958 new_points.append( (TBPoint*)point ); 09959 } 09960 09961 stat = create_surface( new_points, new_body, NULL); 09962 09963 if(project_points && surface_ptr) 09964 { 09965 for( i=0; i<new_vec_list.size(); i++ ) 09966 { 09967 CubitVector *vec_ptr = new_vec_list.get_and_step(); 09968 delete vec_ptr; 09969 } 09970 } 09971 return stat; 09972 } 09973 09974 //================================================================================ 09975 // Description: Creates a surface using a list of points. 09976 // Those points are connected into a closed wire and then 09977 // a surface is created on it. 09978 // Author : Jane Hu 09979 // Date : 02/11 09980 //================================================================================ 09981 CubitStatus 09982 OCCModifyEngine::create_surface( DLIList<TBPoint*>& points, 09983 BodySM *&new_body, 09984 Surface * /*on_surface*/ )const 09985 { 09986 TBPoint *start_point = points.get_and_step(); 09987 DLIList<Curve*> curve_list; 09988 for(int i = 0; i < points.size(); i++) 09989 { 09990 CubitVector coord1 = start_point->coordinates(); 09991 TBPoint *end_point = points.get_and_step(); 09992 CubitVector coord2 = end_point->coordinates(); 09993 if(coord1.within_tolerance( coord2, GEOMETRY_RESABS ) ) 09994 { 09995 PRINT_ERROR( "Attempt to create a line between coincident points at (%f, %f, %f)\n", 09996 coord1.x(), coord1.y(), coord1.z() ); 09997 for(int j=0; j<curve_list.size(); j++ ) 09998 { 09999 Curve* curve_ptr = curve_list.get_and_step(); 10000 OCCQueryEngine::instance()->delete_solid_model_entities( curve_ptr ); 10001 } 10002 return CUBIT_FAILURE; 10003 } 10004 10005 Curve* curve = make_Curve(start_point, end_point); 10006 curve_list.append(curve); 10007 start_point = end_point; 10008 } 10009 10010 //make surface out of curves. 10011 Surface* surf = make_Surface(BEST_FIT_SURFACE_TYPE, curve_list); 10012 OCCSurface* occ_surf; 10013 if(surf) 10014 occ_surf = CAST_TO(surf, OCCSurface); 10015 else 10016 { 10017 PRINT_ERROR("Failed to create a surface from given points. \n"); 10018 return CUBIT_FAILURE; 10019 } 10020 new_body = occ_surf->my_body(); 10021 return CUBIT_SUCCESS; 10022 } 10023 10024 10025 //================================================================================ 10026 // Description: Creates a weld surface. 10027 // Author : Tyronne Lim 10028 // Date : 08/18/03 10029 //================================================================================ 10030 CubitStatus OCCModifyEngine::create_weld_surface( CubitVector & /*root*/, 10031 Surface * /*ref_face1*/, 10032 double /*leg1*/, 10033 Surface * /*ref_face2*/, 10034 double /*leg2*/, 10035 BodySM *& /*new_body*/ ) const 10036 { 10037 PRINT_ERROR("Function not implemented in this engine.\n"); 10038 return CUBIT_FAILURE; 10039 } 10040 10041 CubitStatus OCCModifyEngine::scale( BodySM *&body, const CubitVector& factors ) 10042 { 10043 return OCCQueryEngine::instance()->scale( body, factors ); 10044 } 10045 10046 //================================================================================ 10047 // Description: According to what I read in ModifyEngine, 10048 // bridges_in are already the invalid_tbs, and we want to 10049 // get all vertices, edges and surfaces below bridges_in into 10050 // bridges_out. 10051 // Author : Jane Hu 10052 // Date : 02/11 10053 //================================================================================ 10054 void OCCModifyEngine::get_possible_invalid_tbs( 10055 DLIList<TopologyBridge*> &bridges_in, 10056 DLIList<TopologyBridge*> &bridges_out) 10057 { 10058 DLIList<OCCSurface*> surfaces; 10059 DLIList<OCCCurve*> curves; 10060 DLIList<OCCPoint*> points; 10061 10062 for (int i = 0; i < bridges_in.size(); i++) 10063 { 10064 TopologyBridge* tb_in = bridges_in.get_and_step(); 10065 if(! tb_in) 10066 continue; 10067 10068 OCCBody *occ_body = NULL; 10069 if(OCCLump * lump_ptr = CAST_TO( tb_in,OCCLump)) 10070 { 10071 BodySM* body = lump_ptr->get_body(); 10072 assert (body); 10073 occ_body = CAST_TO(body, OCCBody); 10074 } 10075 10076 else if( occ_body || (occ_body = CAST_TO( tb_in, OCCBody))) 10077 { 10078 occ_body->get_all_surfaces(surfaces); 10079 occ_body->get_all_curves(curves); 10080 occ_body->get_all_points(points); 10081 } 10082 10083 else if(OCCSurface *surface_ptr = CAST_TO( tb_in, OCCSurface)) 10084 { 10085 surface_ptr->get_curves(curves); 10086 surface_ptr->get_points(points); 10087 surfaces.append(surface_ptr); 10088 } 10089 else if( OCCCurve *curve_ptr = CAST_TO( tb_in, OCCCurve)) 10090 { 10091 curves.append(curve_ptr); 10092 curve_ptr->get_points(points); 10093 } 10094 else if( OCCPoint *point_ptr = CAST_TO( tb_in, OCCPoint)) 10095 { 10096 points.append(point_ptr); 10097 } 10098 } 10099 for (int i = 0; i < surfaces.size(); i++) 10100 bridges_out.append((TopologyBridge*)surfaces.get_and_step()); 10101 for (int i = 0; i < curves.size(); i++) 10102 bridges_out.append((TopologyBridge*)curves.get_and_step()); 10103 for (int i = 0; i < points.size(); i++) 10104 bridges_out.append((TopologyBridge*)points.get_and_step()); 10105 } 10106 CubitStatus OCCModifyEngine::curve_surface_intersection( Surface *surface, 10107 Curve* curve, 10108 DLIList<Curve*> &new_curves ) const 10109 { 10110 return CUBIT_FAILURE; 10111 } 10112 10113 BodySM* OCCModifyEngine::make_extended_sheet( DLIList<Surface*> &surface_list, 10114 CubitBox *clip_box_ptr, 10115 bool preview ) const 10116 { 10117 PRINT_ERROR("This feature is not implemented.\n"); 10118 return (BodySM*) NULL; 10119 } 10120 10121 CubitStatus OCCModifyEngine::remove_topology(DLIList<Curve*> &curves_to_remove, 10122 DLIList<Surface*> &surfs_to_remove, 10123 double backoff_distance, 10124 double small_edge_size, 10125 DLIList<BodySM*> &new_bodysm_list, 10126 CubitBoolean preview) const 10127 { 10128 PRINT_ERROR("This feature is not implemented.\n"); 10129 return CUBIT_FAILURE;; 10130 } 10131 10132 CubitStatus OCCModifyEngine::tolerant_imprint( DLIList<BodySM*> &bodies_in, 10133 DLIList<BodySM*> &new_bodies, 10134 DLIList<TopologyBridge*>*, 10135 DLIList<TopologyBridge*>* ) const 10136 { 10137 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 10138 return CUBIT_FAILURE; 10139 } 10140 10141 CubitStatus OCCModifyEngine::tolerant_imprint(DLIList<Surface*> &surfs_in, 10142 DLIList<BodySM*> &new_bodysm_list) const 10143 { 10144 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 10145 return CUBIT_FAILURE; 10146 } 10147 10148 CubitStatus OCCModifyEngine::tolerant_imprint_surface_with_curves( 10149 Surface *surface_to_imprint, 10150 DLIList<Curve*> &curves, 10151 DLIList<TopologyBridge*> &temporary_bridges, 10152 BodySM *&new_body, 10153 DLIList<TopologyBridge*> *new_tbs, 10154 DLIList<TopologyBridge*> *att_tbs) const 10155 { 10156 PRINT_ERROR("Option not supported for OCC based geometry.\n"); 10157 return CUBIT_FAILURE; 10158 } 10159 10160 //=============================================================================== 10161 // Function : get_new_tbs 10162 // Member Type: PUBLIC 10163 // Description: given old list of surfaces, curves and points, and new list 10164 // of surfaces, curves and points, using physical comparison to 10165 // find out what entities are newly generated by imprinting. 10166 // And add imprint feature on the new entities. 10167 // Author : Jane HU 10168 // Date : 02/11 10169 //=============================================================================== 10170 void OCCModifyEngine::get_new_tbs( 10171 std::map<OCCSurface*, std::pair<CubitVector, double> >& surf_property_map, 10172 std::map<OCCCurve*, std::pair<CubitVector, double> >& curve_property_map, 10173 DLIList<OCCPoint*> &points, 10174 DLIList<OCCSurface*> &new_surfaces, 10175 DLIList<OCCCurve*> &new_curves, 10176 DLIList<OCCPoint*> &new_points, 10177 DLIList<TopologyBridge*> *new_tbs)const 10178 { 10179 /* 10180 CubitSimpleAttrib *tmp_attrib = new CubitSimpleAttrib( "SOURCE_FEATURE", "IMPRINT" ); 10181 10182 CubitBoolean found = false; 10183 for (int i = 0; i < new_surfaces.size() ; i++) 10184 { 10185 OCCSurface* new_surf = new_surfaces.get_and_step(); 10186 double new_d = new_surf->measure(); 10187 CubitVector new_center = new_surf->center_point(); 10188 std::map<OCCSurface*, std::pair<CubitVector, int> >::iterator it = 10189 surf_property_map.find( new_surf); 10190 if(it != surf_property_map.end()) 10191 { 10192 std::pair<CubitVector, int> pair; 10193 pair = it->second; 10194 double d = pair.second; 10195 CubitVector center = pair.first; 10196 surf_property_map.erase(it); 10197 if(center.about_equal(new_center) && fabs(d- new_d) <= TOL) 10198 found = true; 10199 } 10200 if(!found) 10201 { 10202 new_tbs->append(new_surf); 10203 //Add an imprint feature to the topo. 10204 TopoDS_Face* new_shape = new_surf->get_TopoDS_Face(); 10205 OCCAttribSet::append_attribute(tmp_attrib, *new_shape); 10206 } 10207 found = false; 10208 } 10209 10210 for (int i = 0; i < new_curves.size() ; i++) 10211 { 10212 OCCCurve* new_curve = new_curves.get_and_step(); 10213 double new_d = new_curve->measure(); 10214 CubitVector new_center; 10215 new_curve->position_from_u(0.5, new_center); 10216 std::map<OCCCurve*, std::pair<CubitVector, int> >::iterator it = 10217 curve_property_map.find(new_curve); 10218 if( it != curve_property_map.end()) 10219 { 10220 std::pair<CubitVector, int> pair; 10221 pair = it->second; 10222 double d = pair.second; 10223 CubitVector center = pair.first; 10224 curve_property_map.erase(it); 10225 if(center.about_equal(new_center) && fabs(d- new_d) <= TOL) 10226 found = true; 10227 } 10228 if(!found) 10229 { 10230 new_tbs->append(new_curve); 10231 //Add an imprint feature to the topo. 10232 TopoDS_Edge* new_shape = new_curve->get_TopoDS_Edge(); 10233 OCCAttribSet::append_attribute(tmp_attrib, *new_shape); 10234 } 10235 found = false; 10236 } 10237 10238 int num_new_points = new_points.size() -points.size(); 10239 if(num_new_points > 0) 10240 { 10241 int new_vertices_count = 0; 10242 CubitBoolean found = false; 10243 for( int i = 0; i < new_points.size() && new_vertices_count < num_new_points; i++) 10244 { 10245 OCCPoint* new_point = new_points.get_and_step(); 10246 for(int j = 0; j < points.size(); j ++) 10247 { 10248 OCCPoint* point = points.get(); 10249 if(point == new_point) 10250 { 10251 found = true; 10252 points.remove(); 10253 break; 10254 } 10255 points.step(); 10256 } 10257 if(!found) 10258 { 10259 new_tbs->append(new_point); 10260 new_vertices_count ++; 10261 //Add an imprint feature to the topo. 10262 TopoDS_Vertex* new_shape = new_point->get_TopoDS_Vertex(); 10263 OCCAttribSet::append_attribute(tmp_attrib, *new_shape); 10264 } 10265 found = false; 10266 } 10267 } 10268 delete tmp_attrib; 10269 */ 10270 } 10271 10272 //=============================================================================== 10273 // Function : get_att_tbs 10274 // Member Type: PUBLIC 10275 // Description: given new list of surfaces, curves and points for modified 10276 // bodies, find out what entities are "name" entities 10277 // Author : Jane HU 10278 // Date : 02/11 10279 //=============================================================================== 10280 void OCCModifyEngine::get_att_tbs(DLIList<OCCSurface*> &new_surfaces, 10281 DLIList<OCCCurve*> &new_curves, 10282 DLIList<OCCPoint*> &new_points, 10283 const CubitString& name, 10284 DLIList<TopologyBridge*> *att_tbs)const 10285 { 10286 DLIList<CubitSimpleAttrib> csa_list; 10287 for (int i = 0 ; i < new_surfaces.size(); i++) 10288 { 10289 OCCSurface* occ_surf = new_surfaces.get_and_step(); 10290 csa_list.clean_out(); 10291 occ_surf->get_simple_attribute(name, csa_list); 10292 if(csa_list.size() > 0) 10293 att_tbs->append(occ_surf); 10294 } 10295 10296 for (int i = 0 ; i < new_curves.size(); i++) 10297 { 10298 OCCCurve* occ_curve = new_curves.get_and_step(); 10299 csa_list.clean_out(); 10300 occ_curve->get_simple_attribute(name, csa_list); 10301 if(csa_list.size() > 0) 10302 att_tbs->append(occ_curve); 10303 } 10304 10305 for (int i = 0 ; i < new_points.size(); i++) 10306 { 10307 OCCPoint* occ_point = new_points.get_and_step(); 10308 csa_list.clean_out(); 10309 occ_point->get_simple_attribute(name, csa_list); 10310 if(csa_list.size() > 0) 10311 att_tbs->append(occ_point); 10312 } 10313 } 10314 10315 Curve* OCCModifyEngine::create_arc_radius(const CubitVector ¢er, 10316 TBPoint* ref_vertex_start, 10317 TBPoint* ref_vertex_end, 10318 const CubitVector &normal, 10319 double radius, 10320 bool full , 10321 CubitBoolean preview ) 10322 { 10323 CubitVector v1 = ref_vertex_start->coordinates(); 10324 CubitVector v2 = ref_vertex_end->coordinates(); 10325 if ((2 * radius) < v1.distance_between(v2)) 10326 { 10327 PRINT_ERROR("Unable to create acr from given radius and vertices. \n"); 10328 return (Curve*) NULL; 10329 } 10330 OCCPoint* center_point = new OCCPoint(center); 10331 Curve* curve = create_arc_center_edge(center_point, ref_vertex_start, 10332 ref_vertex_end, 10333 normal, radius, full , preview ); 10334 delete center_point; 10335 10336 return curve; 10337 } 10338 10339 Curve* OCCModifyEngine::create_arc(const CubitVector& position, 10340 double radius, 10341 double start_angle,//in degree 10342 double end_angle,//in degree 10343 CubitVector plane, 10344 bool preview ) 10345 { 10346 gp_Pnt P(position.x(), position.y(), position.z()); 10347 gp_Dir normal(plane.x(), plane.y(), plane.z()); 10348 gp_Ax1 axis(P, normal); 10349 Handle(Geom_Circle) curve_ptr; 10350 curve_ptr = GC_MakeCircle( axis, radius); 10351 gp_Circ circle = curve_ptr->Circ(); 10352 start_angle *= CUBIT_PI/180; 10353 end_angle *= CUBIT_PI/180; 10354 CubitBoolean sense = CUBIT_TRUE ; 10355 10356 Handle_Geom_TrimmedCurve new_curve_ptr; 10357 new_curve_ptr = GC_MakeArcOfCircle(circle, start_angle, end_angle, sense); 10358 TopoDS_Edge new_edge = BRepBuilderAPI_MakeEdge(new_curve_ptr); 10359 Curve* new_curve = OCCQueryEngine::instance()->populate_topology_bridge(new_edge); 10360 if(preview) 10361 { 10362 GfxPreview::clear(); 10363 OCCCurve* occ_curve = CAST_TO(new_curve, OCCCurve); 10364 TopoDS_Edge* h_edge = occ_curve->get_TopoDS_Edge(); 10365 // Draw this edge 10366 OCCDrawTool::instance()->draw_EDGE( h_edge, CUBIT_BLUE_INDEX, CUBIT_TRUE ); 10367 10368 OCCQueryEngine::instance()->delete_solid_model_entities(new_curve); 10369 return (Curve*) NULL; 10370 } 10371 else 10372 return new_curve; 10373 } 10374 10375 CubitStatus OCCModifyEngine::webcut_across_translate( 10376 DLIList<BodySM*>& body_list, 10377 Surface* plane_surf1, 10378 Surface* plane_surf2, 10379 DLIList<BodySM*>& neighbor_imprint_list, 10380 DLIList<BodySM*>& results_list, 10381 ImprintType imprint_type , 10382 bool preview ) const 10383 { 10384 PRINT_WARNING("Not implemented yet. \n"); 10385 return CUBIT_FAILURE; 10386 } 10387 //void OCCModifyEngine::start_tracking_history( DLIList<TopologyBridge*> &bridges, 10388 // OCCHistory &history_object, 10389 // bool ignore_parents ) 10390 //{ 10391 //} 10392 10393 //void OCCModifyEngine::stop_tracking_history( DLIList<BodySM*> &new_bodies, 10394 // OCCHistory &history_object ) 10395 //{ 10396 // DLIList<TopologyBridge*> tbs; 10397 // CAST_LIST( new_bodies, tbs, TopologyBridge ); 10398 10399 //stop_tracking_history( tbs, history_object ); 10400 //} 10401 10402 //Following codes are OCC engine only, implemented by Boyd Tidwell 10403 CubitStatus OCCModifyEngine::create_rectangle_surface( double width, 10404 double height, 10405 CubitVector plane, 10406 BodySM *&sheet_body) const 10407 { 10408 //create points at the 4 corners 10409 CubitVector pos1( width*0.5, height*0.5, 0 ); 10410 CubitVector pos2( -width*0.5, height*0.5, 0 ); 10411 CubitVector pos3( -width*0.5, -height*0.5, 0 ); 10412 CubitVector pos4( width*0.5, -height*0.5, 0 ); 10413 10414 DLIList<CubitVector*> vec_list(4); 10415 vec_list.append( &pos1 ); 10416 vec_list.append( &pos2 ); 10417 vec_list.append( &pos3 ); 10418 vec_list.append( &pos4 ); 10419 10420 CubitStatus status = create_surface(vec_list, sheet_body, 0, CUBIT_FALSE ); 10421 10422 //rotate it so that it is aligned with the plane defined by vector 'plane' 10423 10424 CubitVector current_plane(0,0,1); 10425 if (!plane.about_equal(current_plane)) 10426 { 10427 CubitVector axis_of_rotation = current_plane * plane; 10428 double angle_of_rotation = axis_of_rotation.vector_angle( 10429 current_plane, plane ); 10430 10431 OCCQueryEngine::instance()->rotate( sheet_body, axis_of_rotation, 10432 RADIANS_TO_DEGREES(angle_of_rotation) ); 10433 } 10434 10435 return status; 10436 } 10437 10438 CubitStatus OCCModifyEngine::create_ellipse_surface( TBPoint *pt1, 10439 TBPoint *pt3, 10440 CubitVector center_point, 10441 BodySM *&sheet_body) const 10442 { 10443 // make ellipse by creating two ellipse arcs in each sense direction 10444 Curve *ellipse1 = make_elliptical_Curve( pt1, pt3, center_point, 0, 360, CUBIT_FORWARD ); 10445 if( NULL == ellipse1 ) 10446 return CUBIT_FAILURE; 10447 DLIList<Curve*> curve_list(2); 10448 curve_list.append( ellipse1 ); 10449 10450 Curve *ellipse2 = make_elliptical_Curve( pt1, pt3, center_point, 0, 360, CUBIT_REVERSED ); 10451 if( NULL == ellipse2 ) 10452 return CUBIT_FAILURE; 10453 curve_list.append( ellipse2 ); 10454 10455 Surface *tmp_surface = make_Surface( PLANE_SURFACE_TYPE, curve_list, NULL, false ); 10456 if( NULL == tmp_surface ) 10457 return CUBIT_FAILURE; 10458 sheet_body = make_BodySM( tmp_surface ); 10459 if( NULL == sheet_body) 10460 return CUBIT_FAILURE; 10461 10462 return CUBIT_SUCCESS; 10463 } 10464 10465 CubitStatus OCCModifyEngine::create_ellipse_surface( double major_radius, 10466 double minor_radius, 10467 CubitVector plane, 10468 BodySM *&sheet_body) const 10469 { 10470 //create the points 10471 CubitVector tmp_pt( major_radius, 0, 0 ); 10472 TBPoint *pt1 = make_Point( tmp_pt ); 10473 10474 tmp_pt.set( 0, minor_radius, 0 ); 10475 TBPoint *pt2 = make_Point( tmp_pt ); 10476 10477 CubitVector center_point(0,0,0); 10478 10479 // make ellipse by creating two ellipse arcs in each sense direction 10480 Curve *ellipse1 = make_elliptical_Curve( pt1, pt2, center_point, 0, 360, CUBIT_FORWARD ); 10481 if( NULL == ellipse1 ) 10482 return CUBIT_FAILURE; 10483 DLIList<Curve*> curve_list(2); 10484 curve_list.append( ellipse1 ); 10485 10486 Curve *ellipse2 = make_elliptical_Curve( pt1, pt2, center_point, 0, 360, CUBIT_REVERSED ); 10487 if( NULL == ellipse2 ) 10488 return CUBIT_FAILURE; 10489 curve_list.append( ellipse2 ); 10490 10491 Surface *tmp_surface = make_Surface(PLANE_SURFACE_TYPE, curve_list, NULL, false ); 10492 if( NULL == tmp_surface ) 10493 return CUBIT_FAILURE; 10494 10495 sheet_body = make_BodySM( tmp_surface ); 10496 if( NULL == sheet_body) 10497 return CUBIT_FAILURE; 10498 10499 //rotate it so that it is aligned with the plane defined by vector 'plane' 10500 CubitVector current_plane(0,0,1); 10501 if (!plane.about_equal(current_plane)) 10502 { 10503 CubitVector axis_of_rotation = current_plane * plane; 10504 double angle_of_rotation = axis_of_rotation.vector_angle(current_plane, plane ); 10505 10506 OCCQueryEngine::instance()->rotate( sheet_body, axis_of_rotation, 10507 RADIANS_TO_DEGREES(angle_of_rotation) ); 10508 } 10509 10510 return CUBIT_SUCCESS; 10511 } 10512 10513 Curve* OCCModifyEngine::make_elliptical_Curve( TBPoint const* point1, 10514 TBPoint const* point2, 10515 CubitVector ¢er_point, 10516 double start_angle, 10517 double end_angle, 10518 CubitSense sense) const 10519 { 10520 GeometryType curve_type = ELLIPSE_CURVE_TYPE; 10521 Curve *curve = NULL; 10522 if(sense ==CUBIT_FORWARD) 10523 curve = make_Curve(curve_type, point1, point2, ¢er_point ); 10524 else 10525 curve = make_Curve(curve_type, point2, point1, ¢er_point ); 10526 if ( curve == NULL ) 10527 { 10528 PRINT_ERROR("In OCCModifyEngine::make_elliptical_Curve\n" 10529 " Cannot make Curve object.\n"); 10530 return (Curve *)NULL; 10531 } 10532 return curve; 10533 } 10534 10535 //circle surface passes three points. 10536 CubitStatus OCCModifyEngine::create_circle_surface( TBPoint *pt1, 10537 CubitVector center_point, 10538 TBPoint *pt3, 10539 BodySM *&sheet_body)const 10540 { 10541 CubitVector * center = new CubitVector(center_point); 10542 Curve *circle = make_Curve( ARC_CURVE_TYPE, pt1, pt3, center); 10543 delete center; 10544 10545 DLIList<Curve*> curve_list(1); 10546 curve_list.append( circle ); 10547 Surface *tmp_surface = make_Surface(PLANE_SURFACE_TYPE, curve_list, NULL, false ); 10548 10549 if( NULL == tmp_surface ) 10550 return CUBIT_FAILURE; 10551 10552 sheet_body = make_BodySM( tmp_surface ); 10553 if( NULL == sheet_body) 10554 return CUBIT_FAILURE; 10555 10556 return CUBIT_SUCCESS; 10557 } 10558 10559 //circle surface passes pt1, pt3, and centered at center_point. 10560 CubitStatus OCCModifyEngine::create_circle_surface( TBPoint *pt1, 10561 TBPoint *pt3, 10562 CubitVector center_point, 10563 BodySM *&sheet_body)const 10564 { 10565 CubitVector v1 = pt1->coordinates(); 10566 CubitVector v3 = pt3->coordinates(); 10567 CubitVector normal(0,0,0); 10568 CubitVector dir1 = v1 - center_point; 10569 CubitVector dir2 = v3 - center_point; 10570 10571 normal = dir1 * dir2; 10572 if(normal.length() < TOL) 10573 { 10574 PRINT_ERROR("The given points can't decide the surface plane. \n"); 10575 return CUBIT_FAILURE; 10576 } 10577 Handle(Geom_Circle) curve_ptr; 10578 gp_Dir norm(normal.x(), normal.y(), normal.z()); 10579 gp_Pnt center = gp_Pnt( center_point.x(), center_point.y(), center_point.z()); 10580 10581 double radius = v1.distance_between(center_point); 10582 curve_ptr = GC_MakeCircle(center,norm,radius); 10583 10584 OCCPoint* occ_pt1 = CAST_TO(const_cast<TBPoint*>(pt1),OCCPoint); 10585 TopoDS_Vertex * vt1 = occ_pt1->get_TopoDS_Vertex(); 10586 TopoDS_Edge new_edge; 10587 new_edge = BRepBuilderAPI_MakeEdge(curve_ptr, *vt1, *vt1); 10588 10589 Curve* circle = OCCQueryEngine::instance()-> 10590 populate_topology_bridge(new_edge, CUBIT_TRUE); 10591 DLIList<Curve*> curve_list(1); 10592 curve_list.append( circle ); 10593 Surface *tmp_surface = make_Surface(PLANE_SURFACE_TYPE, curve_list, NULL, 10594 false ); 10595 if( NULL == tmp_surface ) 10596 return CUBIT_FAILURE; 10597 10598 sheet_body = OCCModifyEngine::instance()->make_BodySM( tmp_surface ); 10599 if( NULL == sheet_body) 10600 return CUBIT_FAILURE; 10601 10602 return CUBIT_SUCCESS; 10603 } 10604 10605 CubitStatus OCCModifyEngine::create_circle_surface( double radius, 10606 CubitVector plane, 10607 BodySM *&sheet_body) const 10608 { 10609 CubitVector center_pt; 10610 center_pt.set(0, 0, 0); 10611 CubitVector pt2, pt3; 10612 if (plane.x() > 0 ) 10613 { 10614 pt2.set( 0, radius, 0 ); 10615 pt3.set( 0, 0, radius); 10616 } 10617 else if (plane.y() > 0) 10618 { 10619 pt2.set(radius, 0, 0); 10620 pt3.set(0, 0, -radius); 10621 } 10622 else if (plane.z() > 0) 10623 { 10624 pt2.set(radius, 0, 0); 10625 pt3.set(0, radius, 0); 10626 } 10627 else 10628 { 10629 PRINT_ERROR("In OCCModifyEngine::create_circle_surface\n" 10630 " Invalid plane specified.\n"); 10631 return CUBIT_FAILURE; 10632 } 10633 10634 TBPoint *tbpt2 = make_Point( pt2 ); 10635 TBPoint *tbpt3 = make_Point( pt3 ); 10636 10637 CubitStatus stat = create_circle_surface(tbpt2, tbpt3, center_pt, sheet_body); 10638 return stat; 10639 10640 } 10641 10642 CubitStatus OCCModifyEngine::tolerant_imprint( DLIList<BodySM*> &bodies_in, 10643 DLIList<BodySM*> &new_bodies, 10644 double overlap_tol, 10645 double imprint_tol, 10646 DLIList<TopologyBridge*> *new_tbs, 10647 DLIList<TopologyBridge*> *att_tbs) const 10648 { 10649 return CUBIT_FAILURE; 10650 } 10651 10652 #ifdef CGM_KCM 10653 CubitStatus OCCModifyEngine::mesh2brep(std::vector<double> &xvals, 10654 std::vector<double> &yvals, 10655 std::vector<double> &zvals, 10656 std::vector<unsigned int> &tri_connectivity, 10657 DLIList<BodySM*> &new_body_sms) const 10658 { 10659 return CUBIT_FAILURE; 10660 } 10661 #endif 10662 10663 // EOF