cgma
OCCSurface.cpp
Go to the documentation of this file.
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 &degree_u,
01353   int &degree_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 &center,
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 &center,
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 &center,
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         **********
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines