cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : OCCSurface.cpp 00003 // 00004 // Purpose : 00005 // 00006 // Special Notes : 00007 // 00008 // Creator : Alexander Danilov 00009 // 00010 // Creation Date : 00011 // 00012 // Owner : 00013 //------------------------------------------------------------------------- 00014 00015 // ********** BEGIN OCC INCLUDES ********** 00016 #include "OCCSurface.hpp" 00017 #include "OCCQueryEngine.hpp" 00018 00019 #include "OCCBody.hpp" 00020 #include "OCCLump.hpp" 00021 #include "OCCShell.hpp" 00022 #include "OCCLoop.hpp" 00023 #include "OCCCoEdge.hpp" 00024 #include "OCCCurve.hpp" 00025 #include "OCCPoint.hpp" 00026 #include "OCCAttribSet.hpp" 00027 #include "GfxDebug.hpp" 00028 #include "OCCDrawTool.hpp" 00029 // ********** END OCC INCLUDES ********** 00030 00031 // ********** BEGIN CUBIT INCLUDES ********** 00032 00033 #include "CubitVector.hpp" 00034 #include "GeometryDefines.h" 00035 #include "CubitUtil.hpp" 00036 #include "CastTo.hpp" 00037 #include "GeometryQueryEngine.hpp" 00038 #include "DLIList.hpp" 00039 #include "ShellSM.hpp" 00040 #include "Lump.hpp" 00041 #include "LoopSM.hpp" 00042 // ********** END CUBIT INCLUDES ********** 00043 00044 00045 // ********** BEGIN OpenCascade INCLUDES ********** 00046 00047 #include <BRepAdaptor_Surface.hxx> 00048 #include <TopExp.hxx> 00049 #include <TopTools_IndexedMapOfShape.hxx> 00050 #include <Bnd_Box.hxx> 00051 #include <BndLib_AddSurface.hxx> 00052 #include <Precision.hxx> 00053 #include <TopoDS.hxx> 00054 #include <Extrema_ExtPS.hxx> 00055 #include <BRepLProp_SLProps.hxx> 00056 #include <BRepGProp.hxx> 00057 #include <GProp_GProps.hxx> 00058 #include "TopTools_ListIteratorOfListOfShape.hxx" 00059 #include "TopTools_DataMapOfShapeInteger.hxx" 00060 #include "TopTools_IndexedDataMapOfShapeListOfShape.hxx" 00061 #include "BRepClass_FaceClassifier.hxx" 00062 #include "BRepBuilderAPI_ModifyShape.hxx" 00063 #include "BRepAlgoAPI_BooleanOperation.hxx" 00064 #include "BRepBuilderAPI_MakeShape.hxx" 00065 #include "BRepBuilderAPI_Transform.hxx" 00066 #include "BRepBuilderAPI_GTransform.hxx" 00067 #include "BRepFilletAPI_MakeFillet2d.hxx" 00068 #include "BRepTools_WireExplorer.hxx" 00069 #include "TopExp.hxx" 00070 #include "BRep_Tool.hxx" 00071 #include "BRep_Builder.hxx" 00072 #include "LocOpe_SplitShape.hxx" 00073 #include "TopoDS_Compound.hxx" 00074 #include "BRepExtrema_DistShapeShape.hxx" 00075 #include "Geom_BSplineSurface.hxx" 00076 #include "IntCurvesFace_ShapeIntersector.hxx" 00077 #include "TColgp_Array2OfPnt.hxx" 00078 #include "TColStd_Array2OfReal.hxx" 00079 #include "TColStd_Array1OfReal.hxx" 00080 #include "gp_Dir.hxx" 00081 #include "gp_Lin.hxx" 00082 #include "gp_Pnt.hxx" 00083 #include "gp_Sphere.hxx" 00084 #include "gp_Cone.hxx" 00085 #include "gp_Torus.hxx" 00086 // ********** END OpenCascade INCLUDES ********** 00087 00088 00089 // ********** BEGIN STATIC DECLARATIONS ********** 00090 // ********** END STATIC DECLARATIONS ********** 00091 00092 00093 // ********** BEGIN PUBLIC FUNCTIONS ********** 00094 00095 //------------------------------------------------------------------------- 00096 // Purpose : The constructor with a pointer to the TopoDS_Face. 00097 // 00098 // Special Notes : 00099 // 00100 //------------------------------------------------------------------------- 00101 OCCSurface::OCCSurface(TopoDS_Face *theFace) 00102 { 00103 myTopoDSFace = theFace; 00104 myShell = NULL; 00105 myLump = NULL; 00106 myBody = NULL; 00107 if(myTopoDSFace && !myTopoDSFace->IsNull()) 00108 assert(myTopoDSFace->ShapeType() == TopAbs_FACE); 00109 } 00110 00111 00112 OCCSurface::~OCCSurface() 00113 { 00114 if(myTopoDSFace) 00115 { 00116 myTopoDSFace->Nullify(); 00117 delete (TopoDS_Face*)myTopoDSFace; 00118 myTopoDSFace = NULL; 00119 } 00120 } 00121 00122 void OCCSurface::set_TopoDS_Face(TopoDS_Face& face) 00123 { 00124 if(myTopoDSFace && face.IsEqual(*myTopoDSFace)) 00125 return; 00126 00127 if(myTopoDSFace) 00128 myTopoDSFace->Nullify(); 00129 *myTopoDSFace = face ; 00130 } 00131 00132 00133 //------------------------------------------------------------------------- 00134 // Purpose : The purpose of this function is to append a 00135 // attribute to the GE. The name is attached to the 00136 // underlying solid model entity this one points to. 00137 // 00138 // 00139 // Special Notes : 00140 // 00141 //------------------------------------------------------------------------- 00142 void OCCSurface::append_simple_attribute_virt(const CubitSimpleAttrib &csa) 00143 { OCCAttribSet::append_attribute(csa, *myTopoDSFace); } 00144 00145 00146 //------------------------------------------------------------------------- 00147 // Purpose : The purpose of this function is to remove a simple 00148 // attribute attached to this geometry entity. The name is 00149 // removed from the underlying BODY this points to. 00150 // 00151 // Special Notes : 00152 // 00153 //------------------------------------------------------------------------- 00154 void OCCSurface::remove_simple_attribute_virt(const CubitSimpleAttrib &csa) 00155 { OCCAttribSet::remove_attribute( csa , *myTopoDSFace); } 00156 00157 00158 //------------------------------------------------------------------------- 00159 // Purpose : The purpose of this function is to remove all simple 00160 // attributes attached to this geometry entity. Also 00161 // removes lingering GTC attributes. 00162 // 00163 // 00164 // Special Notes : 00165 // 00166 //------------------------------------------------------------------------- 00167 void OCCSurface::remove_all_simple_attribute_virt() 00168 { 00169 OCCAttribSet::remove_attribute(CubitSimpleAttrib(), *myTopoDSFace); 00170 } 00171 00172 00173 //------------------------------------------------------------------------- 00174 // Purpose : The purpose of this function is to get the 00175 // attributes attached to this geometry entity. The name is 00176 // attached to the underlying BODY this points to. 00177 // 00178 // Special Notes : 00179 // 00180 //------------------------------------------------------------------------- 00181 CubitStatus OCCSurface::get_simple_attribute(DLIList<CubitSimpleAttrib>& 00182 csa_list) 00183 { return OCCAttribSet::get_attributes(*myTopoDSFace,csa_list); } 00184 00185 CubitStatus OCCSurface::get_simple_attribute(const CubitString& name, 00186 DLIList<CubitSimpleAttrib>& csa_list ) 00187 { return OCCAttribSet::get_attributes( name, *myTopoDSFace, csa_list ); } 00188 00189 00190 //------------------------------------------------------------------------- 00191 // Purpose : Get geometry modeling engine: OCCQueryEngine 00192 // 00193 // Special Notes : 00194 // 00195 //------------------------------------------------------------------------- 00196 GeometryQueryEngine* 00197 OCCSurface::get_geometry_query_engine() const 00198 { 00199 return OCCQueryEngine::instance(); 00200 } 00201 00202 00203 CubitStatus OCCSurface::closest_point_along_vector(CubitVector& from_point, 00204 CubitVector& along_vector, 00205 CubitVector& point_on_surface) 00206 { 00207 // define the search ray in a way that OCC will understand 00208 gp_Pnt vectorOrigin(from_point.x(), from_point.y(), from_point.z()); 00209 gp_Dir vectorDir(along_vector.x(), along_vector.y(), along_vector.z()); 00210 gp_Lin occVector(vectorOrigin, vectorDir); 00211 00212 // perform the OCC intersection algorithm 00213 IntCurvesFace_ShapeIntersector csIntersector; 00214 csIntersector.Load(*get_TopoDS_Face(), Precision::Intersection()); 00215 csIntersector.Perform(occVector, 0, 1e63); 00216 00217 // fail if intersection could not be computed or there is no intersection 00218 if (!csIntersector.IsDone() || csIntersector.NbPnt() == 0) 00219 { 00220 return CUBIT_FAILURE; 00221 } 00222 00223 // identify which of the intersection points along the vector is the closest 00224 double minWParam = -1; 00225 int minIndex = 0; 00226 for (int iPntIndx = 1; iPntIndx <= csIntersector.NbPnt(); ++iPntIndx) 00227 { 00228 double wParam = csIntersector.WParameter(iPntIndx); 00229 if (minIndex == 0 || wParam < minWParam) 00230 { 00231 minIndex = iPntIndx; 00232 minWParam = wParam; 00233 } 00234 } 00235 00236 // package and return the closest intersection point 00237 gp_Pnt closestIntPnt = csIntersector.Pnt(minIndex); 00238 point_on_surface.set(closestIntPnt.X(), 00239 closestIntPnt.Y(), closestIntPnt.Z()); 00240 return CUBIT_SUCCESS; 00241 } 00242 00243 //------------------------------------------------------------------------- 00244 // Purpose : Returns a surface type ID -- the values of these are 00245 // determined by OCC. 00246 // 00247 // Special Notes : 00248 // This code is very -specific and could change with 00249 // new versions of . There are #defines for the 00250 // various surface type ID's. These are defined in the 00251 // header files of each of the specific surface classes 00252 // in . 00253 // 00254 // 00255 // Creator : Jane HU 00256 // 00257 // Creation Date : 12/06/07 00258 //------------------------------------------------------------------------- 00259 GeometryType OCCSurface::geometry_type() 00260 { 00261 BRepAdaptor_Surface asurface(*myTopoDSFace); 00262 if (asurface.GetType() == GeomAbs_BezierSurface) 00263 return SPLINE_SURFACE_TYPE; 00264 if (asurface.GetType() == GeomAbs_BSplineSurface) 00265 return SPLINE_SURFACE_TYPE; 00266 if (asurface.GetType() == GeomAbs_Plane) 00267 return PLANE_SURFACE_TYPE; 00268 if (asurface.GetType() == GeomAbs_Cylinder || 00269 asurface.GetType() == GeomAbs_Cone) 00270 return CONE_SURFACE_TYPE; 00271 if (asurface.GetType() == GeomAbs_Sphere) 00272 return SPHERE_SURFACE_TYPE; 00273 if (asurface.GetType() == GeomAbs_Torus) 00274 return TORUS_SURFACE_TYPE; 00275 if (asurface.GetType() == GeomAbs_SurfaceOfRevolution) 00276 return UNDEFINED_SURFACE_TYPE; 00277 if (asurface.GetType() == GeomAbs_SurfaceOfExtrusion) 00278 return UNDEFINED_SURFACE_TYPE; 00279 if (asurface.GetType() == GeomAbs_OffsetSurface) 00280 return UNDEFINED_SURFACE_TYPE; 00281 return UNDEFINED_SURFACE_TYPE; 00282 } 00283 //------------------------------------------------------------------------- 00284 // Purpose : Get the bounding box of the object. 00285 // 00286 // Special Notes : 00287 // 00288 //------------------------------------------------------------------------- 00289 CubitBox OCCSurface::bounding_box() const 00290 { 00291 TopoDS_Face face = *myTopoDSFace; 00292 BRepAdaptor_Surface asurface(face); 00293 Bnd_Box aBox; 00294 BndLib_AddSurface::Add(asurface, Precision::Approximation(), aBox); 00295 double min[3], max[3]; 00296 aBox.Get( min[0], min[1], min[2], max[0], max[1], max[2]); 00297 return CubitBox(min, max); 00298 } 00299 00300 00301 CubitStatus OCCSurface::get_point_normal( CubitVector& location, 00302 CubitVector& normal ) 00303 { 00304 return closest_point( bounding_box().center(), &location, &normal ); 00305 } 00306 00307 CubitStatus OCCSurface::closest_point_uv_guess( 00308 CubitVector const& location, 00309 double& , double& , 00310 CubitVector* closest_location, 00311 CubitVector* unit_normal ) 00312 { 00313 // don't use u and v guesses 00314 return closest_point(location, closest_location, unit_normal); 00315 } 00316 00317 00318 //------------------------------------------------------------------------- 00319 // Purpose : Computes the closest_point on the surface to the input 00320 // location. Optionally, it also computes and returns 00321 // the normal to the surface at closest_location and the 00322 // principal curvatures(1-min, 2-max) 00323 // 00324 //------------------------------------------------------------------------- 00325 CubitStatus OCCSurface::closest_point( CubitVector const& location, 00326 CubitVector* closest_location, 00327 CubitVector* unit_normal_ptr, 00328 CubitVector* curvature_1, 00329 CubitVector* curvature_2) 00330 { 00331 BRepAdaptor_Surface asurface(*myTopoDSFace); 00332 gp_Pnt p(location.x(), location.y(), location.z()), newP(0.0, 0.0, 0.0); 00333 double minDist=0.0, u, v; 00334 int i; 00335 BRepLProp_SLProps SLP(asurface, 2, Precision::PConfusion()); 00336 Extrema_ExtPS ext(p, asurface, Precision::Approximation(), Precision::Approximation()); 00337 if (ext.IsDone() && (ext.NbExt() > 0)) { 00338 for ( i = 1 ; i <= ext.NbExt() ; i++ ) { 00339 if ( (i==1) || (p.Distance(ext.Point(i).Value()) < minDist) ) { 00340 minDist = p.Distance(ext.Point(i).Value()); 00341 newP = ext.Point(i).Value(); 00342 ext.Point(i).Parameter(u, v); 00343 SLP.SetParameters(u, v); 00344 } 00345 } 00346 00347 if (closest_location != NULL) 00348 *closest_location = CubitVector(newP.X(), newP.Y(), newP.Z()); 00349 if (unit_normal_ptr != NULL) { 00350 gp_Dir normal; 00351 if (SLP.IsNormalDefined()) { 00352 normal = SLP.Normal(); 00353 *unit_normal_ptr = CubitVector(normal.X(), normal.Y(), normal.Z()); 00354 } 00355 } 00356 00357 gp_Dir MaxD, MinD; 00358 if (SLP.IsCurvatureDefined()) 00359 { 00360 SLP.CurvatureDirections(MaxD, MinD); 00361 if (curvature_1 != NULL) 00362 *curvature_1 = CubitVector(MinD.X(), MinD.Y(), MinD.Z()); 00363 if (curvature_2 != NULL) 00364 *curvature_2 = CubitVector(MaxD.X(), MaxD.Y(), MaxD.Z()); 00365 } 00366 return CUBIT_SUCCESS; 00367 } 00368 //return as OCC did. 00369 return CUBIT_SUCCESS; 00370 } 00371 00372 //------------------------------------------------------------------------- 00373 // Purpose : Computes the closest_point on the trimmed surface to the 00374 // input location. if the point is not on surface, like in the 00375 // hole of the surface, try to project to one of the curves. 00376 // 00377 // Special Notes : 00378 //------------------------------------------------------------------------- 00379 void OCCSurface::closest_point_trimmed( CubitVector from_point, 00380 CubitVector& point_on_surface) 00381 { 00382 BRepAdaptor_Surface asurface(*myTopoDSFace); 00383 gp_Pnt p(from_point.x(), from_point.y(), from_point.z()), newP(0.0, 0.0, 0.0); 00384 double minDist=0.0; 00385 int i; 00386 Extrema_ExtPS ext(p, asurface, Precision::Approximation(), Precision::Approximation()); 00387 if (ext.IsDone() && (ext.NbExt() > 0)) { 00388 for ( i = 1 ; i <= ext.NbExt() ; i++ ) { 00389 if ( (i==1) || (p.Distance(ext.Point(i).Value()) < minDist) ) { 00390 minDist = p.Distance(ext.Point(i).Value()); 00391 newP = ext.Point(i).Value(); 00392 } 00393 } 00394 point_on_surface = CubitVector(newP.X(), newP.Y(), newP.Z()); 00395 } 00396 else 00397 return; 00398 00399 CubitPointContainment pos = point_containment(point_on_surface); 00400 if(pos == CUBIT_PNT_OUTSIDE) 00401 { 00402 DLIList<OCCCurve*> curves; 00403 int num_curve = get_curves(curves); 00404 double d_min = 0., d; 00405 OCCCurve* the_curve = NULL; 00406 gp_Pnt pt = gp_Pnt(point_on_surface.x(), point_on_surface.y(), 00407 point_on_surface.z()); 00408 TopoDS_Vertex theVertex = BRepBuilderAPI_MakeVertex(pt); 00409 CubitVector closest_location; 00410 do 00411 { 00412 for (i = 0; i < num_curve; i++) 00413 { 00414 OCCCurve* curve = curves.get_and_step(); 00415 TopoDS_Edge* theEdge = curve->get_TopoDS_Edge( ); 00416 BRepExtrema_DistShapeShape distShapeShape(*theEdge, theVertex); 00417 d = distShapeShape.Value(); 00418 if ( i == 0 || d_min > d) 00419 { 00420 d_min = d; 00421 the_curve = curve; 00422 } 00423 } 00424 the_curve->closest_point(point_on_surface, closest_location); 00425 pos = the_curve->point_containment(closest_location); 00426 if(pos == CUBIT_PNT_OUTSIDE) 00427 curves.remove(the_curve); 00428 else 00429 break; 00430 }while(curves.size() > 0); 00431 point_on_surface = closest_location; 00432 } 00433 } 00434 00435 //------------------------------------------------------------------------- 00436 // Purpose : This functions computes the point on the surface that is 00437 // closest to the input location and then calculates the 00438 // magnitudes of the principal curvatures at this (possibly, 00439 // new) point on the surface. Specifying the RefVolume for 00440 // reference is optional. 00441 // 00442 // Special Notes : 00443 // 00444 //------------------------------------------------------------------------- 00445 00446 CubitStatus OCCSurface::principal_curvatures( 00447 CubitVector const& location, 00448 double& curvature_1, 00449 double& curvature_2, 00450 CubitVector* closest_location ) 00451 { 00452 BRepAdaptor_Surface asurface(*myTopoDSFace); 00453 gp_Pnt p(location.x(), location.y(), location.z()), newP(0.0, 0.0, 0.0); 00454 double minDist=0.0, u, v; 00455 int i; 00456 BRepLProp_SLProps SLP(asurface, 2, Precision::PConfusion()); 00457 Extrema_ExtPS ext(p, asurface, Precision::Approximation(), Precision::Approximation()); 00458 if (ext.IsDone() && (ext.NbExt() > 0)) { 00459 for ( i = 1 ; i <= ext.NbExt() ; i++ ) { 00460 if ( (i==1) || (p.Distance(ext.Point(i).Value()) < minDist) ) { 00461 minDist = p.Distance(ext.Point(i).Value()); 00462 newP = ext.Point(i).Value(); 00463 ext.Point(i).Parameter(u, v); 00464 SLP.SetParameters(u, v); 00465 } 00466 } 00467 } 00468 if (closest_location != NULL) 00469 *closest_location = CubitVector(newP.X(), newP.Y(), newP.Z()); 00470 00471 if (SLP.IsCurvatureDefined()) 00472 { 00473 curvature_1 = SLP.MinCurvature(); 00474 curvature_2 = SLP.MaxCurvature(); 00475 } 00476 return CUBIT_SUCCESS; 00477 } 00478 00479 00480 00481 00482 00483 CubitStatus OCCSurface::evaluate( double u, double v, 00484 CubitVector *position, 00485 CubitVector *normal, 00486 CubitVector *curvature1, 00487 CubitVector *curvature2 ) 00488 { 00489 BRepAdaptor_Surface asurface(*myTopoDSFace); 00490 00491 gp_Pnt p = asurface.Value(u, v); 00492 if(position!=NULL) 00493 position->set(p.X(), p.Y(), p.Z()); 00494 00495 00496 BRepLProp_SLProps SLP(asurface, 2, Precision::PConfusion()); 00497 SLP.SetParameters(u, v); 00498 00499 00500 if(normal!=NULL) 00501 { 00502 gp_Dir occ_normal; 00503 //normal of a RefFace point to outside of the material 00504 if (SLP.IsNormalDefined()) 00505 { 00506 occ_normal = SLP.Normal(); 00507 normal->set(occ_normal.X(), occ_normal.Y(), occ_normal.Z()); 00508 } 00509 } 00510 00511 00512 gp_Dir MaxD, MinD; 00513 if (curvature1 && curvature2 && SLP.IsCurvatureDefined()) 00514 { 00515 SLP.CurvatureDirections(MaxD, MinD); 00516 if (curvature1 != NULL) 00517 *curvature1 = CubitVector(MinD.X(), MinD.Y(), MinD.Z()); 00518 if (curvature2 != NULL) 00519 *curvature2 = CubitVector(MaxD.X(), MaxD.Y(), MaxD.Z()); 00520 } 00521 00522 00523 return CUBIT_SUCCESS; 00524 } 00525 00526 //------------------------------------------------------------------------- 00527 // Purpose : Given values of the two parameters, get the position. 00528 // 00529 // Special Notes : 00530 // 00531 //------------------------------------------------------------------------- 00532 CubitVector OCCSurface::position_from_u_v (double u, double v) 00533 { 00534 BRepAdaptor_Surface asurface(*myTopoDSFace, Standard_False); 00535 gp_Pnt p = asurface.Value(u, v); 00536 return CubitVector (p.X(), p.Y(), p.Z()); 00537 } 00538 00539 //------------------------------------------------------------------------- 00540 // Purpose : This function returns the {u, v} coordinates of the point 00541 // on the Surface closest to the input point (specified in 00542 // global space). The closest_location is also returned. 00543 // 00544 // Special Notes : 00545 // 00546 //------------------------------------------------------------------------- 00547 CubitStatus OCCSurface::u_v_from_position( CubitVector const& location, 00548 double& u, 00549 double& v, 00550 CubitVector* closest_location ) 00551 { 00552 BRepAdaptor_Surface asurface(*myTopoDSFace); 00553 gp_Pnt p(location.x(), location.y(), location.z()), newP(0.0, 0.0, 0.0); 00554 double minDist=0.0; 00555 int i; 00556 Extrema_ExtPS ext(p, asurface, Precision::Confusion(), Precision::Confusion()); 00557 if (ext.IsDone() && (ext.NbExt() > 0)) { 00558 for ( i = 1 ; i <= ext.NbExt() ; i++ ) { 00559 if ( (i==1) || (p.Distance(ext.Point(i).Value()) < minDist) ) { 00560 minDist = p.Distance(ext.Point(i).Value()); 00561 newP = ext.Point(i).Value(); 00562 ext.Point(i).Parameter(u, v); 00563 } 00564 } 00565 } 00566 if (closest_location != NULL) *closest_location = CubitVector(newP.X(), newP.Y(), newP.Z()); 00567 return CUBIT_SUCCESS; 00568 } 00569 00570 //------------------------------------------------------------------------- 00571 // Purpose : Determines whether the Facet surface is periodic. Not 00572 // available yet. 00573 // 00574 // 00575 //------------------------------------------------------------------------- 00576 CubitBoolean OCCSurface::is_periodic() 00577 { 00578 BRepAdaptor_Surface asurface(*myTopoDSFace); 00579 return (asurface.IsUPeriodic() || asurface.IsVPeriodic())?CUBIT_TRUE:CUBIT_FALSE; 00580 } 00581 00582 //------------------------------------------------------------------------- 00583 // Purpose : Determines if the face is periodic in the given parameter 00584 // direction. Not available yet. 00585 // 00586 //------------------------------------------------------------------------- 00587 CubitBoolean OCCSurface::is_periodic_in_U( double& period ) 00588 { 00589 00590 BRepAdaptor_Surface asurface(*myTopoDSFace); 00591 if (!asurface.IsUPeriodic()) 00592 return CUBIT_FALSE; 00593 00594 period = asurface.UPeriod(); 00595 return CUBIT_TRUE; 00596 } 00597 00598 //------------------------------------------------------------------------- 00599 // Purpose : Determines if the face is periodic in the given parameter 00600 // direction. Not available yet. 00601 // 00602 // 00603 //------------------------------------------------------------------------- 00604 CubitBoolean OCCSurface::is_periodic_in_V( double& period ) 00605 { 00606 BRepAdaptor_Surface asurface(*myTopoDSFace); 00607 if (!asurface.IsVPeriodic()) 00608 return CUBIT_FALSE; 00609 00610 period = asurface.VPeriod(); 00611 return CUBIT_TRUE; 00612 } 00613 00614 //------------------------------------------------------------------------- 00615 // Purpose : Determines if the face is singular in the given parameter 00616 // direction. Based on comments in Surface: "The 00617 // assumption is made that the u_param is in the 00618 // bounds of the surface. 00619 // 00620 //------------------------------------------------------------------------- 00621 CubitBoolean OCCSurface::is_singular_in_U( double u_param) 00622 { 00623 //from MasterIndex.htm: 00624 // singular_u 00625 // The only singularity recognized is where every value of the 00626 // nonconstant parameter generates the same object-space point, 00627 // and these can only occur at the ends of the parameter range 00628 // as returned by the functions above. A plane is nonsingular 00629 // in both directions. 00630 double u_lower, u_upper; 00631 get_param_range_U( u_lower, u_upper ); 00632 00633 if ( u_param < u_lower - CUBIT_RESABS || 00634 u_param > u_upper + CUBIT_RESABS ) 00635 { 00636 PRINT_ERROR("u parameter is outside parameter bounds.\n"); 00637 return CUBIT_FALSE; 00638 } 00639 00640 //Currently, haven't found any singularity check in OCC. 00641 return CUBIT_FALSE; 00642 } 00643 00644 //------------------------------------------------------------------------- 00645 // Purpose : Determines if the face is singular in the given parameter 00646 // direction. Not available yet. 00647 //------------------------------------------------------------------------- 00648 CubitBoolean OCCSurface::is_singular_in_V( double v_param) 00649 { 00650 double v_lower, v_upper; 00651 get_param_range_V( v_lower, v_upper ); 00652 00653 if ( v_param < v_lower - CUBIT_RESABS || 00654 v_param > v_upper + CUBIT_RESABS ) 00655 { 00656 PRINT_ERROR("v parameter is outside parameter bounds.\n"); 00657 return CUBIT_FALSE; 00658 } 00659 00660 //Currently, haven't found any singularity check in OCC. 00661 return CUBIT_FALSE; 00662 } 00663 00664 //------------------------------------------------------------------------- 00665 // Purpose : Determines if the face is closed in the U parameter. 00666 // 00667 //------------------------------------------------------------------------- 00668 CubitBoolean OCCSurface::is_closed_in_U() 00669 { 00670 BRepAdaptor_Surface asurface(*myTopoDSFace); 00671 return (asurface.IsUClosed())?CUBIT_TRUE:CUBIT_FALSE; 00672 } 00673 00674 //------------------------------------------------------------------------- 00675 // Purpose : Determines if the face is closed in the V parameter. 00676 //------------------------------------------------------------------------- 00677 CubitBoolean OCCSurface::is_closed_in_V() 00678 { 00679 BRepAdaptor_Surface asurface(*myTopoDSFace); 00680 return (asurface.IsVClosed())?CUBIT_TRUE:CUBIT_FALSE; 00681 } 00682 00683 //------------------------------------------------------------------------- 00684 // Purpose : Calculates the derivitives at a given parameter location. 00685 // 00686 //------------------------------------------------------------------------- 00687 CubitStatus OCCSurface::uv_derivitives( double u, 00688 double v, 00689 CubitVector &du, 00690 CubitVector &dv ) 00691 { 00692 BRepAdaptor_Surface asurface(*myTopoDSFace); 00693 gp_Pnt p; 00694 gp_Vec d1u, d1v; 00695 asurface.D1(u, v, p, d1u, d1v); 00696 du = CubitVector(d1u.X(), d1u.Y(), d1u.Z()); 00697 dv = CubitVector(d1v.X(), d1v.Y(), d1v.Z()); 00698 return CUBIT_SUCCESS; 00699 } 00700 00701 //------------------------------------------------------------------------- 00702 // Purpose : Calculates the derivitives at a given parameter location. 00703 // 00704 //------------------------------------------------------------------------- 00705 /* 00706 CubitStatus OCCSurface::uv_2nd_derivitives( double u, 00707 double v, 00708 CubitVector &d2u, 00709 CubitVector &d2v, 00710 CubitVector &d2uv ) 00711 { 00712 BRepAdaptor_Surface asurface(*myTopoDSFace); 00713 gp_Pnt p; 00714 gp_Vec d1u, d1v, du, dv, duv ; 00715 asurface.D2(u, v, p, d1u, d1v, du, dv, duv); 00716 d2u = CubitVector(du.X(), du.Y(), du.Z()); 00717 d2v = CubitVector(dv.X(), dv.Y(), dv.Z()); 00718 d2uv =CubitVector(duv.X(), duv.Y(), duv.Z()); 00719 return CUBIT_SUCCESS; 00720 } 00721 */ 00722 //------------------------------------------------------------------------- 00723 // Purpose : Determines whether the surface is parametrically defined. 00724 // Hopefully later this will be available. 00725 // 00726 //------------------------------------------------------------------------- 00727 CubitBoolean OCCSurface::is_parametric() 00728 { 00729 return CUBIT_TRUE; 00730 } 00731 00732 //------------------------------------------------------------------------- 00733 // Purpose : Returns the lower and upper parametric bounds of the 00734 // surface in U, if it is parametric. Otherwise, it returns 00735 // CUBIT_FALSE and zeroes for the upper and lower parametric 00736 // bounds. 00737 // 00738 // Creator : 00739 // 00740 // Creation Date : 00741 //------------------------------------------------------------------------- 00742 CubitBoolean OCCSurface::get_param_range_U( double& lower_bound, 00743 double& upper_bound ) 00744 { 00745 BRepAdaptor_Surface asurface(*myTopoDSFace); 00746 lower_bound = asurface.FirstUParameter(); 00747 upper_bound = asurface.LastUParameter(); 00748 return CUBIT_TRUE; 00749 } 00750 00751 //------------------------------------------------------------------------- 00752 // Purpose : Returns the lower and upper parametric bounds of the 00753 // surface in V, if it is parametric. Otherwise, it returns 00754 // CUBIT_FALSE and zeroes for the upper and lower parametric 00755 // bounds. 00756 // 00757 //------------------------------------------------------------------------- 00758 CubitBoolean OCCSurface::get_param_range_V( double& lower_bound, 00759 double& upper_bound ) 00760 { 00761 BRepAdaptor_Surface asurface(*myTopoDSFace); 00762 lower_bound = asurface.FirstVParameter(); 00763 00764 upper_bound = asurface.LastVParameter(); 00765 return CUBIT_TRUE; 00766 } 00767 00768 //------------------------------------------------------------------------- 00769 // Purpose : Returns the area of the Surface 00770 // 00771 //------------------------------------------------------------------------- 00772 double OCCSurface::measure() 00773 { 00774 GProp_GProps myProps; 00775 BRepGProp::SurfaceProperties(*myTopoDSFace, myProps); 00776 return myProps.Mass(); 00777 } 00778 00779 //------------------------------------------------------------------------- 00780 // Purpose : Returns the center of the Surface mass 00781 // 00782 //------------------------------------------------------------------------- 00783 CubitVector OCCSurface::center_point() 00784 { 00785 GProp_GProps myProps; 00786 BRepGProp::SurfaceProperties(*myTopoDSFace, myProps); 00787 gp_Pnt pt = myProps.CentreOfMass(); 00788 CubitVector v(pt.X(),pt.Y(), pt.Z()); 00789 return v; 00790 } 00791 00792 //------------------------------------------------------------------------- 00793 // Purpose : This function tests the passed in position to see if 00794 // is on the underlying surface. 00795 // 00796 //------------------------------------------------------------------------- 00797 CubitBoolean OCCSurface::is_position_on( CubitVector &test_position ) 00798 { 00799 CubitVector new_point; 00800 CubitStatus stat = closest_point(test_position, &new_point, NULL,NULL,NULL); 00801 if ( !stat ) 00802 return CUBIT_FALSE; 00803 CubitVector result_vec = test_position - new_point; 00804 if ( result_vec.length_squared() < GEOMETRY_RESABS ) 00805 return CUBIT_TRUE; 00806 return CUBIT_FALSE; 00807 } 00808 00809 CubitPointContainment OCCSurface::point_containment( const CubitVector &point ) 00810 { 00811 TopoDS_Face *face = get_TopoDS_Face(); 00812 gp_Pnt p(point.x(), point.y(), point.z()); 00813 double tol = OCCQueryEngine::instance()->get_sme_resabs_tolerance(); 00814 00815 //It's checking the state of the projected point of THIS Point 00816 BRepClass_FaceClassifier face_classifier; 00817 face_classifier.Perform(*face, p, tol); 00818 TopAbs_State state = face_classifier.State(); 00819 00820 if (state == TopAbs_IN) 00821 return CUBIT_PNT_INSIDE; 00822 else if (state == TopAbs_OUT) 00823 return CUBIT_PNT_OUTSIDE; 00824 else if (state == TopAbs_ON) 00825 return CUBIT_PNT_BOUNDARY; 00826 00827 return CUBIT_PNT_UNKNOWN; 00828 } 00829 00830 CubitPointContainment OCCSurface::point_containment( double u_param, 00831 double v_param ) 00832 { 00833 CubitVector point = position_from_u_v(u_param, v_param); 00834 return point_containment(point); 00835 } 00836 00837 00838 CubitSense OCCSurface::get_geometry_sense() 00839 { 00840 return CUBIT_FORWARD; 00841 } 00842 00843 void OCCSurface::get_parents_virt( DLIList<TopologyBridge*>& parents ) 00844 { 00845 if(myShell) //shell or sheet body 00846 { 00847 parents.append(myShell); 00848 return; 00849 } 00850 00851 OCCQueryEngine* oqe = (OCCQueryEngine*) get_geometry_query_engine(); 00852 OCCBody * body = NULL; 00853 DLIList <OCCBody* > *bodies = oqe->BodyList; 00854 TopTools_IndexedDataMapOfShapeListOfShape M; 00855 for(int i = 0; i < bodies->size(); i++) 00856 { 00857 body = bodies->get_and_step(); 00858 DLIList<OCCSurface*> surfaces; 00859 body = bodies->get_and_step(); 00860 body->get_all_surfaces(surfaces); 00861 if(surfaces.move_to(this)) 00862 { 00863 TopoDS_Shape* shape = oqe->instance()-> 00864 get_TopoDS_Shape_of_entity(CAST_TO(body, TopologyBridge)); 00865 TopExp::MapShapesAndAncestors(*shape, TopAbs_FACE, TopAbs_SHELL, M); 00866 if(!M.Contains(*(get_TopoDS_Face()))) 00867 continue; 00868 const TopTools_ListOfShape& ListOfShapes = 00869 M.FindFromKey(*(get_TopoDS_Face())); 00870 if (!ListOfShapes.IsEmpty()) 00871 { 00872 TopTools_ListIteratorOfListOfShape it(ListOfShapes) ; 00873 for (;it.More(); it.Next()) 00874 { 00875 TopoDS_Shell Shell = TopoDS::Shell(it.Value()); 00876 int k = oqe->OCCMap->Find(Shell); 00877 parents.append((OCCShell*)(oqe->OccToCGM->find(k))->second); 00878 } 00879 } 00880 } 00881 } 00882 } 00883 00884 void OCCSurface::get_children_virt( DLIList<TopologyBridge*>& children ) 00885 { 00886 TopTools_IndexedMapOfShape M; 00887 TopExp::MapShapes(*myTopoDSFace, TopAbs_WIRE, M); 00888 int ii; 00889 for (ii=1; ii<=M.Extent(); ii++) { 00890 TopologyBridge *loop = OCCQueryEngine::instance()->occ_to_cgm(M(ii)); 00891 if(loop) 00892 children.append_unique(loop); 00893 } 00894 } 00895 00896 // return the sense with respect to the given shell 00897 CubitSense OCCSurface::get_shell_sense( ShellSM* shell_ptr ) const 00898 { 00899 OCCShell* shell = dynamic_cast<OCCShell*>(shell_ptr); 00900 if (!shell) // error 00901 return CUBIT_UNKNOWN; 00902 00903 if (shell->is_sheet()) // relative sense is "both" for sheet 00904 return CUBIT_UNKNOWN; 00905 00906 TopoDS_Shell* shellShapePtr = shell->get_TopoDS_Shell(); 00907 if (!shellShapePtr) // error 00908 return CUBIT_UNKNOWN; 00909 00910 TopExp_Explorer shellFaceExp(shellShapePtr->Oriented(TopAbs_FORWARD), 00911 TopAbs_FACE); 00912 bool isForward = false; 00913 bool isReversed = false; 00914 while (shellFaceExp.More()) 00915 { 00916 const TopoDS_Shape shellFace = shellFaceExp.Current(); 00917 if (shellFace.IsSame(*myTopoDSFace)) 00918 { 00919 if (shellFace.Orientation() == TopAbs_FORWARD) 00920 { 00921 isForward = true; 00922 } 00923 else if (shellFace.Orientation() == TopAbs_REVERSED) 00924 { 00925 isReversed = true; 00926 } 00927 else 00928 { 00929 isForward = true; 00930 isReversed = true; 00931 } 00932 } 00933 shellFaceExp.Next(); 00934 } 00935 00936 if (isForward && isReversed) 00937 return CUBIT_UNKNOWN; 00938 if (isReversed) 00939 return CUBIT_REVERSED; 00940 if (isForward) 00941 return CUBIT_FORWARD; 00942 return CUBIT_UNKNOWN; 00943 } 00944 00945 00946 int OCCSurface::get_loops( DLIList<OCCLoop*>& result_list ) 00947 { 00948 TopTools_IndexedMapOfShape M; 00949 TopExp::MapShapes(*myTopoDSFace, TopAbs_WIRE, M); 00950 int ii; 00951 for (ii=1; ii<=M.Extent(); ii++) { 00952 TopologyBridge *loop = OCCQueryEngine::instance()->occ_to_cgm(M(ii)); 00953 if(loop) 00954 result_list.append_unique(dynamic_cast<OCCLoop*>(loop)); 00955 } 00956 return result_list.size(); 00957 } 00958 00959 int OCCSurface::get_coedges( DLIList<OCCCoEdge*>& result_list ) 00960 { 00961 DLIList<OCCLoop*> loop_list; 00962 get_loops( loop_list ); 00963 loop_list.reset(); 00964 for ( int i = 0; i < loop_list.size(); i++ ) 00965 { 00966 result_list += loop_list.next(i)->coedges( ); 00967 } 00968 return result_list.size(); 00969 } 00970 00971 int OCCSurface::get_curves( DLIList<OCCCurve*>& result_list ) 00972 { 00973 DLIList<OCCCoEdge*> coedge_list; 00974 get_coedges( coedge_list ); 00975 coedge_list.reset(); 00976 for ( int i = coedge_list.size(); i--; ) 00977 { 00978 OCCCoEdge* coedge = coedge_list.get_and_step(); 00979 OCCCurve* curve = dynamic_cast<OCCCurve*>(coedge->curve()); 00980 if (curve) 00981 result_list.append_unique(curve); 00982 } 00983 return result_list.size(); 00984 } 00985 00986 int OCCSurface::get_points(DLIList<OCCPoint*>& points) 00987 { 00988 DLIList<OCCCurve*> curves; 00989 int num_crv = get_curves(curves); 00990 for(int i = 0; i < num_crv; i++) 00991 { 00992 OCCCurve* curve = curves.get_and_step(); 00993 curve->get_points(points); 00994 } 00995 points += get_hardpoints(); 00996 return points.size(); 00997 } 00998 00999 //---------------------------------------------------------------- 01000 // Function: to update the core Surface 01001 // for any movement or Boolean operation of the body. 01002 // Author: Jane Hu 01003 //---------------------------------------------------------------- 01004 CubitStatus OCCSurface::update_OCC_entity( BRepBuilderAPI_ModifyShape *aBRepTrsf, 01005 BRepAlgoAPI_BooleanOperation *op) 01006 { 01007 assert(aBRepTrsf != NULL || op != NULL); 01008 TopoDS_Shape shape; 01009 01010 if(aBRepTrsf) 01011 shape = aBRepTrsf->ModifiedShape(*get_TopoDS_Face()); 01012 01013 else 01014 { 01015 TopTools_ListOfShape shapes; 01016 shapes.Assign(op->Modified(*get_TopoDS_Face())); 01017 if(shapes.Extent() == 0) 01018 shapes.Assign(op->Generated(*get_TopoDS_Face())); 01019 if (shapes.Extent() == 1) 01020 shape = shapes.First(); 01021 else if(shapes.Extent() > 1) 01022 { 01023 shape = shapes.First(); 01024 } 01025 else if(op->IsDeleted(*get_TopoDS_Face())) 01026 ; 01027 else 01028 return CUBIT_SUCCESS; 01029 } 01030 01031 TopoDS_Face surface; 01032 if(!shape.IsNull()) 01033 surface = TopoDS::Face(shape); 01034 01035 if (aBRepTrsf) 01036 { 01037 //set the loops 01038 DLIList<OCCLoop *> loops; 01039 this->get_loops(loops); 01040 for (int i = 1; i <= loops.size(); i++) 01041 { 01042 OCCLoop *loop = loops.get_and_step(); 01043 loop->update_OCC_entity(aBRepTrsf, op); 01044 } 01045 OCCQueryEngine::instance()->update_OCC_map(*myTopoDSFace, surface); 01046 } 01047 01048 else if(op) 01049 update_OCC_entity(*myTopoDSFace, surface, op); 01050 01051 return CUBIT_SUCCESS; 01052 } 01053 01054 //---------------------------------------------------------------- 01055 // Function: TopoDS_Shape level function to update the core Surface 01056 // for any movement or Boolean operation of the body. 01057 // Author: Jane Hu 01058 //---------------------------------------------------------------- 01059 CubitStatus OCCSurface::update_OCC_entity(TopoDS_Face& old_surface, 01060 TopoDS_Shape& new_surface, 01061 BRepBuilderAPI_MakeShape *op, 01062 TopoDS_Vertex* removed_vertex, 01063 LocOpe_SplitShape* sp) 01064 { 01065 TopTools_IndexedMapOfShape M, M2; 01066 TopoDS_Shape shape_face, shape, shape2, shape_edge, shape_vertex; 01067 double dTOL = OCCQueryEngine::instance()->get_sme_resabs_tolerance(); 01068 01069 //First check if new_surface is type shell. 01070 TopExp::MapShapes(new_surface, TopAbs_FACE,M); 01071 if(M.Extent() > 1 ) 01072 { 01073 OCCQueryEngine::instance()->update_OCC_map(old_surface, new_surface); 01074 return CUBIT_SUCCESS; 01075 } 01076 01077 01078 if(M.Extent() == 1 ) 01079 shape_face = M(1); 01080 01081 // GfxDebug::clear(); 01083 // OCCDrawTool::instance()->draw_TopoDS_Shape(&shape_face,CUBIT_GREEN,false,true); 01084 // GfxDebug::mouse_xforms(); 01085 01086 01087 M.Clear(); 01088 //set the Wires 01089 TopExp::MapShapes(old_surface, TopAbs_WIRE, M); 01090 01091 TopTools_ListOfShape shapes; 01092 BRepFilletAPI_MakeFillet2d* test_op = NULL; 01093 01094 for (int ii=1; ii<=M.Extent(); ii++) 01095 { 01096 TopoDS_Wire wire = TopoDS::Wire(M(ii)); 01097 TopTools_ListOfShape shapes; 01098 if(op) 01099 { 01100 //test_op = dynamic_cast<BRepFilletAPI_MakeFillet2d*>(op); 01101 test_op = NULL; //casting fails on both OSX and Linux 01102 if(!test_op) 01103 shapes.Assign(op->Modified(wire)); 01104 if(shapes.Extent() == 0) 01105 shapes.Assign(op->Generated(wire)); 01106 if(!new_surface.IsNull()) 01107 TopExp::MapShapes(new_surface,TopAbs_WIRE, M2); 01108 } 01109 else if(sp) 01110 shapes.Assign(sp->DescendantShapes(wire)); 01111 01112 if (shapes.Extent() == 1) 01113 { 01114 shape = shapes.First(); 01115 if(M2.Extent() == 1) 01116 { 01117 shape2 = TopoDS::Wire(M2(1)); 01118 if(!shape.IsSame(shape2)) 01119 shape = shape2; 01120 } 01121 else if(M2.Extent() > 1) 01122 shape.Nullify(); 01123 } 01124 else if(shapes.Extent() > 1) 01125 shape.Nullify(); 01126 else if(op->IsDeleted(wire) || shapes.Extent() == 0) 01127 { 01128 TopTools_IndexedMapOfShape M_new; 01129 TopExp::MapShapes(new_surface, TopAbs_WIRE, M_new); 01130 if (M_new.Extent()== 1) 01131 shape = M_new(1); 01132 else if(!shape_face.IsNull()) 01133 { 01134 M_new.Clear(); 01135 TopExp::MapShapes(shape_face, TopAbs_WIRE, M_new); 01136 if (M_new.Extent()== 1) 01137 shape = M_new(1); 01138 } 01139 else 01140 shape.Nullify(); 01141 } 01142 else 01143 { 01144 shape = wire; 01145 continue; 01146 } 01147 01148 //set curves 01149 BRepTools_WireExplorer Ex; 01150 01151 for(Ex.Init(wire); Ex.More();Ex.Next()) 01152 { 01153 TopoDS_Edge edge = Ex.Current(); 01154 //check to see if the edge made itself into a curve. 01155 GProp_GProps myProps; 01156 BRepGProp::LinearProperties(edge, myProps); 01157 double length = myProps.Mass(); 01158 if(length < dTOL) 01159 continue; 01160 if(op && !test_op) 01161 { 01162 shapes.Assign(op->Modified(edge)); 01163 if(shapes.Extent() == 0) 01164 shapes.Assign(op->Generated(edge)); 01165 } 01166 01167 else if(sp) 01168 shapes.Assign(sp->DescendantShapes(edge)); 01169 01170 if (shapes.Extent() == 1) 01171 { 01172 //in fillet creating mothod, one edge could generated a face, so check 01173 //it here. 01174 TopAbs_ShapeEnum type = shapes.First().TShape()->ShapeType(); 01175 if(type != TopAbs_EDGE) 01176 shape_edge.Nullify(); 01177 else 01178 shape_edge = shapes.First(); 01179 } 01180 else if (shapes.Extent() > 1) 01181 { 01182 //update all attributes first. 01183 TopTools_ListIteratorOfListOfShape it; 01184 it.Initialize(shapes); 01185 for(; it.More(); it.Next()) 01186 { 01187 shape_edge = it.Value(); 01188 OCCQueryEngine::instance()->copy_attributes(edge, shape_edge); 01189 } 01190 shape_edge.Nullify(); 01191 } 01192 else if (op->IsDeleted(edge)) 01193 shape_edge.Nullify(); 01194 else if (test_op) 01195 { 01196 if(!test_op->IsModified(edge)) 01197 shape_edge = edge; 01198 else 01199 shape_edge = (test_op->Modified(edge)).First(); 01200 } 01201 else 01202 shape_edge = edge; 01203 01204 //update vertex 01205 TopoDS_Vertex vertex = Ex.CurrentVertex(); 01206 shapes.Clear(); 01207 if(test_op) 01208 assert(removed_vertex != NULL); 01209 01210 if(op && ! test_op ) 01211 { 01212 shapes.Assign(op->Modified(vertex)); 01213 if(shapes.Extent() == 0) 01214 shapes.Assign(op->Generated(vertex)); 01215 } 01216 if(sp) 01217 shapes.Assign(sp->DescendantShapes(vertex)); 01218 01219 if (shapes.Extent() == 1) 01220 shape_vertex = shapes.First(); 01221 01222 else if(shapes.Extent() > 1) 01223 { 01224 //update all attributes first. 01225 TopTools_ListIteratorOfListOfShape it; 01226 it.Initialize(shapes); 01227 for(; it.More(); it.Next()) 01228 { 01229 shape_vertex = it.Value(); 01230 OCCQueryEngine::instance()->copy_attributes(vertex, shape_vertex); 01231 } 01232 shape_vertex.Nullify() ; 01233 } 01234 else if(op->IsDeleted(vertex) || (test_op && vertex.IsSame( *removed_vertex))) 01235 { 01236 if(!shape.IsNull() && !shape_edge.IsNull() && !shape_edge.Closed()) 01237 //there should be a vertex corresponding to the old_vertex. 01238 //find the vertices within tolerance distance with old_vertex. 01239 { 01240 TopoDS_Iterator It(shape_edge); 01241 for(; It.More(); It.Next()) 01242 { 01243 TopoDS_Vertex v = TopoDS::Vertex(It.Value()); 01244 gp_Pnt pt1 = BRep_Tool::Pnt(v); 01245 gp_Pnt pt2 = BRep_Tool::Pnt(vertex); 01246 if(pt1.IsEqual(pt2, dTOL)) 01247 { 01248 shape_vertex = v; 01249 break; 01250 } 01251 } 01252 } 01253 else 01254 shape_vertex.Nullify() ; 01255 } 01256 else 01257 shape_vertex = vertex; 01258 01259 if(!vertex.IsSame(shape_vertex) ) 01260 OCCQueryEngine::instance()->update_OCC_map(vertex, shape_vertex); 01261 01262 if (!edge.IsSame(shape_edge)) 01263 OCCQueryEngine::instance()->update_OCC_map(edge, shape_edge); 01264 } 01265 if (!wire.IsSame(shape)) 01266 OCCQueryEngine::instance()->update_OCC_map(wire, shape); 01267 } 01268 01269 if (!old_surface.IsSame(new_surface)) 01270 { 01271 TopAbs_ShapeEnum shapetype = TopAbs_SHAPE; 01272 if(!new_surface.IsNull()) 01273 shapetype = new_surface.TShape()->ShapeType(); 01274 if(shapetype == TopAbs_FACE || new_surface.IsNull()) 01275 OCCQueryEngine::instance()->update_OCC_map(old_surface, new_surface); 01276 else 01277 { 01278 TopTools_IndexedMapOfShape M; 01279 TopExp::MapShapes(new_surface, TopAbs_FACE, M); 01280 TopoDS_Shape new_shape; 01281 if(M.Extent() == 1) 01282 new_shape = M(1); 01283 else if(M.Extent() > 1) 01284 { 01285 for(int i = 1; i <= M.Extent(); i++) 01286 { 01287 GProp_GProps myProps; 01288 BRepGProp::SurfaceProperties(old_surface, myProps); 01289 double orig_mass = myProps.Mass(); 01290 gp_Pnt orig_pnt = myProps.CentreOfMass(); 01291 BRepGProp::SurfaceProperties(M(i), myProps); 01292 double after_mass = myProps.Mass(); 01293 gp_Pnt after_pnt = myProps.CentreOfMass(); 01294 if(fabs(-after_mass + orig_mass) <= dTOL && 01295 orig_pnt.IsEqual(after_pnt, dTOL)) 01296 { 01297 new_shape = M(i); 01298 break; 01299 } 01300 } 01301 } 01302 OCCQueryEngine::instance()->update_OCC_map(old_surface, new_shape); 01303 } 01304 } 01305 return CUBIT_SUCCESS; 01306 } 01307 01308 CubitStatus OCCSurface::get_bodies(DLIList<OCCBody*>& bodies) 01309 { 01310 TopoDS_Face* topo_face = this->get_TopoDS_Face(); 01311 OCCQueryEngine* oqe = OCCQueryEngine::instance(); 01312 DLIList <OCCBody* > *all_bodies = oqe->BodyList; 01313 TopTools_IndexedDataMapOfShapeListOfShape M; 01314 OCCBody * body = NULL; 01315 for(int j = 0; j < all_bodies->size(); j++) 01316 { 01317 body = all_bodies->get_and_step(); 01318 TopExp_Explorer Ex; 01319 TopoDS_Face the_face; 01320 TopoDS_Shape* pshape; 01321 body->get_TopoDS_Shape(pshape); 01322 TopoDS_Shape ashape; 01323 if (pshape && !pshape->IsNull() && 01324 pshape->ShapeType() <= TopAbs_FACE && 01325 OCCQueryEngine::instance()->OCCMap->IsBound(*pshape) == Standard_True) 01326 ashape = *pshape; 01327 M.Clear(); 01328 01329 TopExp::MapShapesAndAncestors(ashape, TopAbs_FACE, TopAbs_COMPOUND, M); 01330 if(!M.Contains(*topo_face)) 01331 continue; 01332 bodies.append_unique(body); 01333 } 01334 return CUBIT_SUCCESS; 01335 } 01336 01337 CubitStatus OCCSurface::get_projected_distance_on_surface( CubitVector *pos1, 01338 CubitVector *pos2, 01339 double &distance ) 01340 { 01341 CubitVector closest_point1; 01342 this->closest_point_trimmed(*pos1, closest_point1); 01343 CubitVector closest_point2; 01344 this->closest_point_trimmed(*pos2, closest_point2); 01345 distance = closest_point1.distance_between(closest_point2); 01346 return CUBIT_SUCCESS; 01347 } 01348 01349 CubitStatus OCCSurface::get_nurb_params 01350 ( 01351 bool &rational, 01352 int °ree_u, 01353 int °ree_v, 01354 int &num_cntrl_pts_u, 01355 int &num_cntrl_pts_v, 01356 DLIList<CubitVector> &cntrl_pts, 01357 DLIList<double> &cntrl_pt_weights, 01358 DLIList<double> &u_knots, 01359 DLIList<double> &v_knots 01360 ) const 01361 { 01362 BRepAdaptor_Surface asurf(*myTopoDSFace); 01363 Handle_Geom_BSplineSurface h_S = NULL; 01364 if (asurf.GetType() == GeomAbs_BSplineSurface) 01365 h_S = asurf.BSpline(); 01366 else 01367 return CUBIT_FAILURE; 01368 assert ( h_S != NULL); 01369 01370 if(h_S->IsURational() || h_S->IsVRational()) 01371 rational = true; 01372 else 01373 rational = false; 01374 01375 degree_u = h_S->UDegree(); 01376 degree_v = h_S->VDegree(); 01377 01378 num_cntrl_pts_u = h_S->NbUPoles(); 01379 num_cntrl_pts_v = h_S->NbVPoles(); 01380 01381 TColgp_Array2OfPnt P(1, h_S->NbUPoles(), 1, h_S->NbVPoles()); 01382 h_S->Poles(P); 01383 gp_Pnt cnt_p; 01384 for(int i = P.LowerRow(); i <= P.UpperRow(); i++) 01385 { 01386 for (int j = P.LowerCol(); j <= P.UpperCol(); j++) 01387 { 01388 cnt_p = P(i,j); 01389 cntrl_pts.append(CubitVector(cnt_p.X(), cnt_p.Y(), cnt_p.Z())); 01390 } 01391 } 01392 TColStd_Array2OfReal W(1,h_S->NbUPoles(), 1, h_S->NbVPoles()); 01393 h_S->Weights(W); 01394 for(int i = W.LowerRow(); i <= W.UpperRow(); i++) 01395 { 01396 for (int j = W.LowerCol(); j <= W.UpperCol(); j++) 01397 { 01398 cntrl_pt_weights.append(W(i,j)); 01399 } 01400 } 01401 TColStd_Array1OfReal Ku(1,h_S->NbUKnots()), Kv(1, h_S->NbVKnots()); 01402 h_S->UKnots(Ku); 01403 h_S->VKnots(Kv); 01404 for(int i = Ku.Lower(); i <= Ku.Upper(); i++) 01405 u_knots.append(Ku.Value(i)); 01406 01407 for (int i = Kv.Lower(); i <= Kv.Upper(); i++) 01408 v_knots.append(Kv.Value(i)); 01409 return CUBIT_SUCCESS; 01410 } 01411 //------------------------------------------------------------------------- 01412 // Purpose : Return parameters about a surface assuming that it is 01413 // a spherical surface. If it not CUBIT_FAILURE. 01414 // 01415 // Special Notes : 01416 // 01417 // Creator : Jane Hu 01418 // 01419 // Creation Date : 2/28/2012 01420 //------------------------------------------------------------------------- 01421 CubitStatus OCCSurface::get_sphere_params( CubitVector ¢er, 01422 double &radius ) const 01423 { 01424 if(const_cast<OCCSurface*> (this)->geometry_type() != SPHERE_SURFACE_TYPE) 01425 return CUBIT_FAILURE; 01426 01427 BRepAdaptor_Surface asurface(*myTopoDSFace); 01428 gp_Sphere sphere = asurface.Sphere(); 01429 gp_Pnt center_pt = sphere.Location(); 01430 center = CubitVector(center_pt.X(), center_pt.Y(), center_pt.Z()); 01431 01432 radius = sphere.Radius(); 01433 return CUBIT_SUCCESS; 01434 } 01435 01436 //------------------------------------------------------------------------- 01437 // Purpose : Return parameters about a surface assuming that it is 01438 // a conical surface. If it not CUBIT_FAILURE. 01439 // 01440 // Special Notes : 01441 // 01442 // Creator : Jane Hu 01443 // 01444 // Creation Date : 2/28/2012 01445 //------------------------------------------------------------------------- 01446 CubitStatus OCCSurface::get_cone_params 01447 ( 01448 CubitVector ¢er, 01449 CubitVector &normal, 01450 CubitVector &major_axis, 01451 double &radius_ratio, 01452 double &sine_angle, 01453 double &cos_angle 01454 ) const 01455 { 01456 if(const_cast<OCCSurface*> (this)->geometry_type() != CONE_SURFACE_TYPE) 01457 return CUBIT_FAILURE; 01458 01459 //all cone type surface in OCC have circular base. 01460 BRepAdaptor_Surface asurface(*myTopoDSFace); 01461 gp_Cone cone = asurface.Cone(); 01462 double half_angle = cone.SemiAngle(); 01463 sine_angle = sin(half_angle); 01464 cos_angle = cos(half_angle); 01465 01466 gp_Ax1 axis = cone.Axis(); 01467 gp_Dir dir = axis.Direction(); 01468 normal.set(dir.X(), dir.Y(), dir.Z()); 01469 01470 gp_Pnt center_pt = cone.Location(); 01471 center = CubitVector(center_pt.X(), center_pt.Y(), center_pt.Z()); 01472 01473 gp_Ax1 x_axis = cone.XAxis(); 01474 dir = x_axis.Direction(); 01475 major_axis.set(dir.X(), dir.Y(), dir.Z()); 01476 01477 radius_ratio = 1; 01478 return CUBIT_SUCCESS; 01479 } 01480 01481 //------------------------------------------------------------------------- 01482 // Purpose : Return parameters about a surface assuming that it is 01483 // a torus surface. If it not CUBIT_FAILURE. 01484 // 01485 // Special Notes : 01486 // 01487 // Creator : Jane Hu 01488 // 01489 // Creation Date : 2/28/2012 01490 //------------------------------------------------------------------------- 01491 CubitStatus OCCSurface::get_torus_params 01492 ( 01493 CubitVector ¢er, 01494 CubitVector &normal, 01495 double &major_radius, 01496 double &minor_radius 01497 ) const 01498 { 01499 if(const_cast<OCCSurface*> (this)->geometry_type() != TORUS_SURFACE_TYPE) 01500 return CUBIT_FAILURE; 01501 01502 BRepAdaptor_Surface asurface(*myTopoDSFace); 01503 gp_Torus torus = asurface.Torus(); 01504 gp_Pnt center_pt = torus.Location(); 01505 center = CubitVector(center_pt.X(), center_pt.Y(), center_pt.Z()); 01506 01507 gp_Ax1 axis = torus.Axis(); 01508 gp_Dir dir = axis.Direction(); 01509 normal.set(dir.X(), dir.Y(), dir.Z()); 01510 01511 major_radius = torus.MajorRadius(); 01512 minor_radius = torus.MinorRadius(); 01513 01514 return CUBIT_SUCCESS; 01515 } 01516 // ********** END PUBLIC FUNCTIONS ********** 01517 01518 // ********** BEGIN PROTECTED FUNCTIONS ********** 01519 // ********** END PROTECTED FUNCTIONS ********** 01520 01521 // ********** BEGIN PRIVATE FUNCTIONS ********** 01522 01523 01524 // ********** END PRIVATE FUNCTIONS ********** 01525 01526 // ********** BEGIN HELPER CLASSES ********** 01527 // ********** END HELPER CLASSES ********** 01528 01529 // ********** BEGIN EXTERN FUNCTIONS ********** 01530 // ********** END EXTERN FUNCTIONS ********** 01531 01532 // ********** BEGIN STATIC FUNCTIONS ********** 01533 // ********** END STATIC FUNCTIONS **********