cgma
OCCQueryEngine.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : OCCQueryEngine.cpp
00003 //
00004 // Purpose       : Implementation of the OCCQueryEngine class.
00005 //                 This class provides OCC-based implementations
00006 //                 of various virtual functions in the GeometryQueryEngine
00007 //                 hierarchy.
00008 //
00009 // Special Notes :
00010 //
00011 // Creator       : David R. White
00012 //
00013 // Creation Date : 7/17/00
00014 //
00015 //-------------------------------------------------------------------------
00016 #include <Standard_Version.hxx>
00017 #include <Standard_Stream.hxx>
00018 //#include <Standard_SStream.hxx>
00019 //#include <Standard_String.hxx>
00020 //#include <stringbuf>
00021 #if OCC_VERSION_MINOR < 5
00022   #include "TDataStd_Shape.hxx"
00023   typedef TDataStd_Shape TDataXtd_Shape;
00024   typedef Handle_TDataStd_Shape Handle_TDataXtd_Shape;
00025 #else
00026   #include "TDataXtd_Shape.hxx"
00027 #endif
00028 
00029 #include "BRep_Tool.hxx"
00030 #include "gp_Pnt.hxx"
00031 #include "gp_Ax1.hxx"
00032 #include "gp_Ax2.hxx"
00033 #include "Geom_Surface.hxx"
00034 #include "Geom_Curve.hxx"
00035 #include "Interface_Static.hxx"
00036 #include "BRepBuilderAPI.hxx"
00037 #include "BRepBuilderAPI_Transform.hxx"
00038 #include "BRepBuilderAPI_GTransform.hxx"
00039 #include "BRepBuilderAPI_ModifyShape.hxx"
00040 #include "BRepBuilderAPI_MakeSolid.hxx"
00041 #include "OCCShapeAttributeSet.hpp"
00042 //#include "OCCBinToolsShapeSet.hpp"
00043 #include "BRepBuilderAPI_MakeShell.hxx"
00044 #include "GProp_GProps.hxx"
00045 #include "BRepGProp.hxx"
00046 #include "BRepTools_WireExplorer.hxx"
00047 #include "TColgp_Array1OfPnt.hxx"
00048 #include "Poly_Array1OfTriangle.hxx"
00049 #include "Poly_Triangle.hxx"
00050 #include "BRepAlgoAPI_BooleanOperation.hxx"
00051 #include "Handle_Poly_Triangulation.hxx"
00052 #include "GCPnts_TangentialDeflection.hxx"
00053 #include "BRepAdaptor_Curve.hxx"
00054 #include "TopExp.hxx"
00055 #ifdef HAVE_OCC_STEP
00056 #  include "STEPControl_Reader.hxx"
00057 #  include "STEPControl_Writer.hxx"
00058 #  include "STEPControl_StepModelType.hxx"
00059 #endif
00060 #ifdef HAVE_OCC_IGES
00061 #  include "IGESControl_Reader.hxx"
00062 #  include "IGESControl_Writer.hxx"
00063 #endif
00064 #include "IFSelect_ReturnStatus.hxx"
00065 #include "BndLib_Add3dCurve.hxx"
00066 #include "Poly_Polygon3D.hxx"
00067 #include "Handle_Poly_Polygon3D.hxx"
00068 #include "BRepMesh_FastDiscret.hxx"
00069 #include "OCCQueryEngine.hpp"
00070 #include "OCCModifyEngine.hpp"
00071 #include "Poly_Triangulation.hxx"
00072 #include "TopologyEntity.hpp"
00073 #include "TopologyBridge.hpp"
00074 #include "RefEntity.hpp"
00075 #include "Body.hpp"
00076 #include "Shell.hpp"
00077 #include "Loop.hpp"
00078 #include "Chain.hpp"
00079 #include "RefVolume.hpp"
00080 #include "RefFace.hpp"
00081 #include "RefEdge.hpp"
00082 #include "RefVertex.hpp"
00083 #include "GeometryEntity.hpp"
00084 #include "DLIList.hpp"
00085 #include "CubitBox.hpp"
00086 #include "CubitString.hpp"
00087 #include "OCCPoint.hpp"
00088 #include "OCCCurve.hpp"
00089 #include "OCCCoEdge.hpp"
00090 #include "OCCLoop.hpp"
00091 #include "OCCSurface.hpp"
00092 #include "OCCShell.hpp"
00093 #include "OCCLump.hpp"
00094 #include "OCCBody.hpp"
00095 #include "OCCAttribSet.hpp"
00096 #include "GMem.hpp"
00097 #include "GeometryQueryTool.hpp"
00098 #include "CubitObserver.hpp"
00099 #include "GfxDebug.hpp"
00100 #include <stdio.h>
00101 #include <errno.h>
00102 
00103 #include <BRep_Builder.hxx>
00104 #include <BRepTools.hxx>
00105 #include <TopExp_Explorer.hxx>
00106 #include <TopoDS.hxx>
00107 #include "TopoDS_Compound.hxx"
00108 #include <TopoDS_CompSolid.hxx>
00109 #include <TopoDS_Solid.hxx>
00110 #include <TopoDS_Shell.hxx>
00111 #include <TopoDS_Face.hxx>
00112 #include <TopoDS_Wire.hxx>
00113 #include <TopoDS_Edge.hxx>
00114 #include <TopoDS_Vertex.hxx>
00115 #include <Bnd_Box.hxx>
00116 #include <BndLib_AddSurface.hxx>
00117 #include <Precision.hxx>
00118 #include <BRepAdaptor_Surface.hxx>
00119 #include <TDF_ChildIterator.hxx>
00120 #include <BinTools_ShapeSet.hxx>
00121 #include "Standard_Boolean.hxx"
00122 
00123 #include "TDF_Label.hxx"
00124 #include "TopTools_DataMapOfShapeInteger.hxx"
00125 #include "BRepExtrema_DistShapeShape.hxx"
00126 #include "BRepAlgoAPI_Section.hxx"
00127 #include "BRepBuilderAPI_MakeEdge.hxx"
00128 #include "TDocStd_Document.hxx"
00129 #include "TCollection_ExtendedString.hxx"
00130 #include "gp_Lin.hxx"
00131 using namespace NCubitFile;
00132 
00133 #include "CGMEngineDynamicLoader.hpp"
00134 
00135 
00136 CGM_ENGINE_EXPORT_CREATE_GQE(OpenCascade)
00137 {
00138   return OCCQueryEngine::instance();
00139 }
00140 
00141 OCCQueryEngine* OCCQueryEngine::instance_ = NULL;
00142 
00143 typedef std::map<int, TopologyBridge*>::value_type valType;
00144 typedef std::map<int, TDF_Label>::value_type labType;
00145 int OCCQueryEngine::iTotalTBCreated = 0;
00146 int OCCQueryEngine::total_coedges = 0;
00147 #define NUM_PTS_UV 30
00148 //================================================================================
00149 // Description:
00150 // Author     :
00151 // Date       :
00152 //================================================================================
00153 OCCQueryEngine* OCCQueryEngine::instance()
00154 {
00155   if (instance_ == NULL ) {
00156     instance_ = new OCCQueryEngine;
00157   }
00158   return instance_;
00159 }
00160 
00161 //================================================================================
00162 // Description:  default constructor
00163 // Author     :
00164 // Date       :
00165 //================================================================================
00166 OCCQueryEngine::OCCQueryEngine()
00167 {
00168   GeometryQueryTool::instance()->add_gqe( this );
00169   OCCMap = new TopTools_DataMapOfShapeInteger;
00170   OccToCGM = new std::map<int, TopologyBridge*>;
00171   Shape_Label_Map = new std::map<int, TDF_Label>;
00172   BodyList = new DLIList<OCCBody*>;
00173   WireList = new DLIList<OCCLoop*>;
00174   SurfaceList = new DLIList<OCCSurface*>;
00175   CurveList = new DLIList<OCCCurve*>;
00176   CubitString name("Doc");
00177   TCollection_ExtendedString xString((Standard_CString)name.c_str(), CUBIT_TRUE);
00178   MyDF = new TDocStd_Document(xString);
00179   mainLabel = MyDF->Main();
00180   EXPORT_ATTRIB = CUBIT_TRUE;
00181 }
00182 
00183 //================================================================================
00184 // Description:  destructor
00185 // Author     :
00186 // Date       :
00187 //================================================================================
00188 OCCQueryEngine::~OCCQueryEngine()
00189 {
00190   instance_ = NULL;
00191   delete OCCMap;
00192   delete OccToCGM;
00193   delete Shape_Label_Map;
00194   delete BodyList;
00195   delete WireList;
00196   delete SurfaceList;
00197   delete CurveList;
00198 }
00199 
00200 int OCCQueryEngine::get_major_version()
00201 {
00202   return OCC_VERSION_MAJOR;
00203 }
00204 
00205 int OCCQueryEngine::get_minor_version()
00206 {
00207   return OCC_VERSION_MINOR;
00208 }
00209 
00210 int OCCQueryEngine::get_subminor_version()
00211 {
00212   return OCC_VERSION_MAINTENANCE;
00213 }
00214 
00215 CubitString OCCQueryEngine::get_engine_version_string()
00216 {
00217   return CubitString("OpenCascade ") + OCC_VERSION_STRING;
00218 }
00219 
00220 //================================================================================
00221 // Description:
00222 // Author     :
00223 // Date       :
00224 //================================================================================
00225 const type_info& OCCQueryEngine::entity_type_info() const
00226 {
00227   return typeid(OCCQueryEngine);
00228 }
00229 
00230 //================================================================================
00231 // Description: reflect body about an axis
00232 // Author     : sjowen
00233 // Date       : 9/7/01
00234 //================================================================================
00235 CubitStatus OCCQueryEngine::reflect( BodySM *bodysm,
00236                                      const CubitVector& axis)
00237 {
00238   OCCBody *body = CAST_TO(bodysm, OCCBody);
00239   if (!body)
00240     {
00241       PRINT_ERROR("Attempt to reflect OCC-based geometry Body.  This body is not OCCBody.");
00242       return CUBIT_FAILURE;
00243     }
00244 
00245   body->reflect( axis.x(), axis.y(), axis.z() );
00246 
00247   return CUBIT_SUCCESS;
00248 }
00249 
00250 
00251 //================================================================================
00252 // Description:  This function queries OCC for the necessary facets
00253 //               information needed in facetting a RefFace.  This
00254 //               information is stored and output in gMem.  The
00255 //               number of triangles, points and facets are also
00256 //               output.
00257 //               normal_tolerance is in degree.
00258 //               max_edge_length is not considered in getting graphics.
00259 // Author     :  Jane Hu
00260 // Date       :  10/25/07
00261 //================================================================================
00262 CubitStatus OCCQueryEngine::get_graphics( Surface* surface_ptr,
00263                                           GMem* g_mem,
00264                                           unsigned short normal_tolerance,
00265                                           double distance_tolerance,
00266                                           double max_edge_length) const
00267 {
00268   // Because this may be unnecessarily called twice,
00269   // say there is one triangle.
00270   if (!g_mem)
00271       return CUBIT_SUCCESS;
00272 
00273   if(max_edge_length > get_sme_resabs_tolerance())
00274   {
00275     PRINT_WARNING("OCC surface's tessilation doesn't consider edge_length.\n");
00276     PRINT_WARNING("max_edge_length argument is ignored. \n");
00277   }
00278 
00279   OCCSurface *occ_surface_ptr = CAST_TO(surface_ptr, OCCSurface);
00280   TopoDS_Face * Topo_Face = occ_surface_ptr->get_TopoDS_Face();
00281 
00282   return get_graphics( Topo_Face, g_mem, normal_tolerance, distance_tolerance, max_edge_length );
00283 }
00284 
00285 CubitStatus OCCQueryEngine::get_graphics( TopoDS_Face* face_ptr,
00286                                           GMem* g_mem,
00287                                           unsigned short normal_tolerance,
00288                                           double distance_tolerance,
00289                                          double max_edge_length) const
00290 {
00291   if (!face_ptr)
00292     return CUBIT_FAILURE;
00293 
00294   TopLoc_Location L;
00295   Handle_Poly_Triangulation facets = BRep_Tool::Triangulation(*face_ptr, L);
00296 
00297   gp_Trsf tf = L.Transformation();
00298 
00299   if(facets.IsNull() || facets->NbTriangles() == 0)
00300   {
00301     //do triangulation
00302     if(distance_tolerance <= 0.0)
00303       distance_tolerance = 0.01;
00304     double angle  = CUBIT_PI * normal_tolerance/180;
00305     BRepAdaptor_Surface asurface(*face_ptr);
00306     Bnd_Box aBox;
00307     BndLib_AddSurface::Add(asurface, Precision::Approximation(), aBox);
00308     BRepMesh_FastDiscret *myMesh =
00309 #if OCC_VERSION_MAJOR <= 6 && OCC_VERSION_MINOR < 8
00310       new BRepMesh_FastDiscret(distance_tolerance, *face_ptr, aBox, angle, Standard_True, Standard_True);
00311 #else
00312       new BRepMesh_FastDiscret(*face_ptr, distance_tolerance, angle, aBox, Standard_True, Standard_True);
00313 #endif
00314     if (myMesh != NULL) delete myMesh;
00315     facets = BRep_Tool::Triangulation(*face_ptr, L);
00316     if(facets.IsNull() || facets->NbTriangles() == 0)
00317     {
00318       PRINT_ERROR("Can't get triangulation representation for this surface.\n");
00319       return CUBIT_FAILURE;
00320     }
00321   }
00322   //if necessary, the face tolerance can be returned. now, no use.
00323   //double tol = BRep_Tool::Tolerance(*Topo_Face);   
00324 
00325   int  number_points = facets->NbNodes();
00326   int  number_triangles = facets->NbTriangles();
00327   int  number_facets = 4 * number_triangles; 
00328   
00329   Poly_Array1OfTriangle triangles(0, number_triangles-1);
00330   triangles.Assign( facets->Triangles() );
00331   int *facetList =  new int[number_facets];
00332   //needs to test that N1, N2, N3 index are starting from 0 to number_points-1
00333   //otherwise needs to update either facetList or gPnts to make consistent.
00334   //It's possible also that N's starting from 1.
00335   int minN = 100;
00336   for (int i = 0; i < triangles.Length(); i++)
00337     {
00338       Poly_Triangle triangle = triangles.Value( i );
00339       int N1, N2, N3;
00340       triangle.Get(N1, N2, N3); 
00341       facetList[4 * i] = 3;
00342       facetList[4 * i + 1] = N1;
00343       minN = (minN < N1 ? minN : N1);
00344       facetList[4 * i + 2] = N2;
00345       minN = (minN < N2 ? minN : N2);
00346       facetList[4 * i + 3] = N3;
00347       minN = (minN < N3 ? minN : N3);
00348     } 
00349   if(minN != 0)
00350   {
00351     //subtract the minN from the facetList for all i+1, i+2, i+3 points
00352     for (int i = 0; i < triangles.Length(); i++)
00353     {
00354       facetList[4 * i + 1] -= minN;
00355       facetList[4 * i + 2] -= minN;
00356       facetList[4 * i + 3] -= minN;
00357     }
00358   }
00359   g_mem->replace_facet_list( facetList, number_facets, number_facets); 
00360 
00361   TColgp_Array1OfPnt points(0,  number_points-1);
00362   points.Assign(facets->Nodes());
00363   GPoint *gPnts= new GPoint[number_points];
00364   for (int i = 0; i < number_points ; i ++)
00365     {
00366       gp_Pnt gp_pnt = points.Value(i);
00367       if( !L.IsIdentity())
00368         gp_pnt.Transform(tf);
00369 
00370       GPoint gPnt;
00371       gPnt.x = gp_pnt.X();
00372       gPnt.y = gp_pnt.Y();
00373       gPnt.z = gp_pnt.Z();
00374       gPnts[i] = gPnt;
00375     }
00376   g_mem->replace_point_list( gPnts, number_points, number_points );
00377 
00378   return CUBIT_SUCCESS;
00379 }
00380 
00381 //================================================================================
00382 // Description: This function queries OCC for the edge information
00383 //              needed in facetting a RefEdge.  This information is
00384 //              stored and output in g_mem.
00385 // Author     : Jane Hu
00386 // Date       : 10/26/07
00387 //================================================================================
00388 CubitStatus OCCQueryEngine::get_graphics( Curve* curve_ptr,
00389                                           GMem* gMem,
00390                                           double angle_tolerance,
00391                                           double distance_tolerance,
00392                                           double max_edge_length ) const
00393 {
00394   //  get the OCCCurve.
00395   OCCCurve *occ_curve_ptr = CAST_TO(curve_ptr,OCCCurve);
00396   assert (gMem);
00397 
00398   if(max_edge_length > get_sme_resabs_tolerance())
00399   {
00400     PRINT_WARNING("OCC surface's tessilation doesn't consider edge_length.\n");
00401     PRINT_WARNING("max_edge_length argument is ignored. \n");
00402   }
00403     
00404   TopoDS_Edge *edge_ptr = occ_curve_ptr->get_TopoDS_Edge();
00405 
00406   return get_graphics( edge_ptr, gMem, angle_tolerance, distance_tolerance, max_edge_length );  
00407 }
00408 
00409 
00410 
00411 CubitStatus OCCQueryEngine::get_graphics( TopoDS_Edge* edge_ptr,
00412                                           GMem* gMem,
00413                                           double angle_tolerance,
00414                                           double distance_tolerance,
00415                                           double max_edge_length ) const
00416 {
00417   if (!edge_ptr)
00418     return CUBIT_FAILURE;
00419 
00420   //do tessellation
00421   if(distance_tolerance <= 0.0)
00422     distance_tolerance = 0.2;
00423   if(angle_tolerance == 0.0)
00424     angle_tolerance = 5;
00425   double angle  = CUBIT_PI * angle_tolerance/180;
00426   BRepAdaptor_Curve acurve(*edge_ptr);
00427   GCPnts_TangentialDeflection *myMesh = 
00428         new GCPnts_TangentialDeflection(acurve, angle, 
00429                                         distance_tolerance);
00430   if (myMesh == NULL) 
00431   {
00432     PRINT_ERROR("Can't tessellate for this curve.\n");
00433     return CUBIT_FAILURE;
00434   }
00435   int num_points = myMesh->NbPoints();
00436 
00440   GPoint *gPnts= new GPoint[num_points];
00441   for (int i = 1; i <= num_points ; i ++)
00442     {
00443       gp_Pnt gp_pnt = myMesh->Value(i);
00444       GPoint gPnt;
00445       gPnt.x = gp_pnt.X();
00446       gPnt.y = gp_pnt.Y();
00447       gPnt.z = gp_pnt.Z();
00448       gPnts[i-1] = gPnt;
00449     }
00450   gMem->replace_point_list( gPnts, num_points, num_points );
00451  
00452   delete myMesh;
00453   return CUBIT_SUCCESS;
00454 }
00455 
00456 //================================================================================
00457 // Description: Given surface and number of point on u and v parametric
00458 //              direction, find the 3-d point locations
00459 // Author     : Jane Hu
00460 // Date       : 10/22/07
00461 //================================================================================
00462 CubitStatus OCCQueryEngine::get_isoparametric_points(Surface* surface,
00463                                                      int &nu, int &nv,
00464                                                      GMem*& g_mem) const
00465 {
00466   OCCSurface* occ_surface = CAST_TO(surface, OCCSurface);
00467   TopoDS_Face* Tops_face = occ_surface->get_TopoDS_Face();
00468   if (Tops_face == NULL)
00469   {
00470     PRINT_ERROR("This surface is not OCCSurface.");
00471     return CUBIT_FAILURE;
00472   }
00473   Handle_Geom_Surface HGeom_surface = BRep_Tool::Surface(*Tops_face);
00474 
00475   double u1, u2, v1, v2;
00476   BRepTools::UVBounds(*Tops_face, u1, u2, v1, v2);
00477 
00478   assert (nu > 1 && nv > 1);
00479   if(nu <= 1)
00480     nu = NUM_PTS_UV;
00481   if(nv <= 1)
00482     nv = NUM_PTS_UV;
00483   g_mem = new GMem[nu];
00484  
00485 
00486   // calculate the nu curves
00487   double interval_u = (u2-u1)/double(nu-1);
00488   double interval_v = (v2 - v1)/(double)(nv - 1);
00489 
00490   for (int i = 0; i < nu; i++)
00491   {
00492     Handle_Geom_Curve HGeom_curve = HGeom_surface->UIso(u1 + i * interval_u); 
00493     g_mem[i].allocate_polylines(nv-1);
00494     for (int j = 0; j <  nv; j++)
00495       {
00496         gp_Pnt pnt = HGeom_curve->Value(v1 + j * interval_v);
00497         g_mem[i].point_list()[j].x = pnt.X();
00498         g_mem[i].point_list()[j].y = pnt.Y();
00499         g_mem[i].point_list()[j].z = pnt.Z();
00500       }
00501     g_mem[i].pointListCount = nv;
00502   }
00503 
00504   return CUBIT_SUCCESS;
00505 }
00506 
00507 CubitStatus OCCQueryEngine::get_u_isoparametric_points(Surface* surface,
00508                                                        double v, int&n,
00509                                                        GMem*& g_mem) const
00510 {
00511   OCCSurface* occ_surface = CAST_TO(surface, OCCSurface);
00512   TopoDS_Face* Tops_face = occ_surface->get_TopoDS_Face();
00513   TopoDS_Face the_face;
00514   if (Tops_face == NULL)
00515     {
00516       PRINT_ERROR("This surface is not OCCSurface.");
00517       return CUBIT_FAILURE;
00518     }
00519 
00520   the_face = *Tops_face;
00521 
00522   Handle_Geom_Surface HGeom_surface = BRep_Tool::Surface(the_face);
00523 
00524   //n must be given to calculate the points.
00525   if (n <= 1)
00526     n = NUM_PTS_UV;
00527   double u1, u2, v1, v2;
00528   HGeom_surface->Bounds(u1, u2, v1, v2);
00529   double interval = (u2 - u1)/(n -1); 
00530   
00531   Handle_Geom_Curve HGeom_curve = HGeom_surface->VIso(v);
00532   g_mem = new GMem;
00533   g_mem->allocate_polylines(n-1);
00534   for (int j = 0; j < n; j++)
00535     {
00536       gp_Pnt pnt = HGeom_curve->Value(u1 + j * interval);
00537       g_mem->point_list()[j].x = pnt.X();
00538       g_mem->point_list()[j].y = pnt.Y();
00539       g_mem->point_list()[j].z = pnt.Z();
00540     }
00541   g_mem->pointListCount = n;
00542 
00543   return CUBIT_SUCCESS;
00544 }
00545 
00546 CubitStatus OCCQueryEngine::get_v_isoparametric_points(Surface* surface,
00547                                                        double u, int&n,
00548                                                        GMem*&g_mem) const
00549 {
00550   OCCSurface* occ_surface = CAST_TO(surface, OCCSurface);
00551   TopoDS_Face* Tops_face = occ_surface->get_TopoDS_Face();
00552   TopoDS_Face the_face;
00553   if (Tops_face == NULL)
00554     {
00555       PRINT_ERROR("This surface is not OCCSurface.");
00556       return CUBIT_FAILURE;
00557     }
00558 
00559   the_face = *Tops_face;
00560 
00561   Handle_Geom_Surface HGeom_surface = BRep_Tool::Surface(the_face);
00562 
00563   if (n <= 1)
00564     n = NUM_PTS_UV;
00565   double u1, u2, v1, v2;
00566   HGeom_surface->Bounds(u1, u2, v1, v2);
00567   double interval = (v2 - v1)/(n -1);
00568 
00569   Handle_Geom_Curve HGeom_curve = HGeom_surface->UIso(u);
00570   g_mem = new GMem;
00571   g_mem->allocate_polylines(n-1);
00572   for (int j = 0; j < n; j++)
00573     {
00574       gp_Pnt pnt = HGeom_curve->Value(v1 + j * interval);
00575       g_mem->point_list()[j].x = pnt.X();
00576       g_mem->point_list()[j].y = pnt.Y();
00577       g_mem->point_list()[j].z = pnt.Z();
00578     }
00579   g_mem->pointListCount = n;
00580 
00581   return CUBIT_SUCCESS;
00582 }
00583 
00584 //================================================================================
00585 // Description:
00586 // Author     :
00587 // Date       :
00588 //================================================================================
00589 CubitStatus OCCQueryEngine::transform_vec_position( CubitVector const& ,
00590                                                     BodySM *,
00591                                                     CubitVector & ) const
00592 {
00593   //Nobody is using this function in  yet.
00594   PRINT_ERROR("Option not supported for OCC based geometry.\n");
00595   return CUBIT_FAILURE;
00596 }
00597 
00598 //================================================================================
00599 // Description:  Calculate for intersection points between a curve and 
00600 //               a segment defined by two points or
00601 //               between two curves or between a curve and a surface.
00602 // Author     :  Jane Hu
00603 // Date       :  10/15/07
00604 //================================================================================
00605 CubitStatus OCCQueryEngine::get_intersections( Curve* curve, 
00606                                                CubitVector& point1,
00607                                                CubitVector& point2,
00608                                                DLIList<CubitVector>& intscts,
00609                                                CubitBoolean bounded,
00610                                                CubitBoolean closest)
00611 {
00612   OCCCurve *occ_curve =  CAST_TO(curve, OCCCurve);
00613   if (occ_curve == NULL)
00614     {
00615       PRINT_ERROR("Option not supported for non-occ based geometry.\n");
00616       return CUBIT_FAILURE;
00617     }
00618 
00619   OCCPoint *pt1 = new OCCPoint(point1);
00620   OCCPoint *pt2 = new OCCPoint(point2);
00621   Curve *curve2 = 
00622     OCCModifyEngine::instance()->make_Curve(pt1, pt2);
00623   if (curve2 == NULL)
00624     {
00625       PRINT_ERROR( "Unable to create OCC EDGE from points\n" );
00626       return CUBIT_FAILURE;
00627     }
00628   
00629   OCCCurve *occ_curve2 = CAST_TO(curve2, OCCCurve);
00630   CubitStatus stat = get_intersections(occ_curve, occ_curve2, intscts, bounded, closest);
00631   delete_solid_model_entities(occ_curve2);
00632   return stat;
00633 }
00634 
00635 CubitStatus OCCQueryEngine::get_intersections( Curve* curve1, 
00636                                                Curve* curve2,
00637                                                DLIList<CubitVector>& intscts,
00638                                                CubitBoolean bounded,
00639                                                CubitBoolean closest)
00640 {
00641   //If this function has shortcomes in using BRepExtrema_DistShapeShape,
00642   //look also at IntTools_EdgeEdge.
00643   OCCCurve *occ_curve1 =  CAST_TO(curve1, OCCCurve);
00644   if (occ_curve1 == NULL)
00645     {
00646       PRINT_ERROR("Option not supported for non-occ based geometry.\n");
00647       return CUBIT_FAILURE;
00648     }
00649 
00650   OCCCurve *occ_curve2 =  CAST_TO(curve2, OCCCurve);
00651   if (occ_curve2 == NULL)
00652     {
00653       PRINT_ERROR("Option not supported for non-occ based geometry.\n");
00654       return CUBIT_FAILURE;
00655     }
00656 
00657   //currently, there's no effect on 'closest' argument or bounded.
00658   BRepExtrema_DistShapeShape distShapeShape(
00659                                             *(occ_curve1->get_TopoDS_Edge()),
00660                                             *(occ_curve2->get_TopoDS_Edge()));
00661 
00662   //distShapeShape.Perform();
00663   if (!distShapeShape.IsDone())
00664     {
00665       PRINT_ERROR("Cannot calculate the intersection points for the input curves.\n");
00666       return CUBIT_FAILURE;
00667     }
00668   
00669   if (distShapeShape.Value() < get_sme_resabs_tolerance())
00670     {
00671       int numPnt = distShapeShape.NbSolution();
00672       for (int i = 1; i <= numPnt; i++)
00673     {
00674       gp_Pnt aPoint = distShapeShape.PointOnShape1(i);
00675      
00676       CubitVector cv(aPoint.X(), aPoint.Y(), aPoint.Z());
00677       intscts.append(cv);
00678     }
00679     }
00680   return CUBIT_SUCCESS;
00681 }
00682 
00683 CubitStatus
00684 OCCQueryEngine::get_intersections( Curve* curve, Surface* surface,
00685                                    DLIList<CubitVector>& intscts,
00686                                    CubitBoolean bounded )
00687 {
00688   // There's no effect of bounded =  false. 
00689   OCCCurve *occ_curve =  CAST_TO(curve, OCCCurve);
00690   if (occ_curve == NULL)
00691     {
00692       PRINT_ERROR("Option not supported for non-occ based geometry.\n");
00693       return CUBIT_FAILURE;
00694     }
00695 
00696   OCCSurface *occ_surface =  CAST_TO(surface, OCCSurface);
00697   if (occ_surface == NULL)
00698     {
00699       PRINT_ERROR("Option not supported for non-occ based geometry.\n");
00700       return CUBIT_FAILURE;
00701     }
00702    
00703   //currently, there's no effect on 'closest' argument or bounded.
00704   BRepExtrema_DistShapeShape distShapeShape(*(occ_curve->get_TopoDS_Edge()),
00705                                             *(occ_surface->get_TopoDS_Face()));
00706 
00707   //distShapeShape.Perform();
00708   if (!distShapeShape.IsDone())
00709     {
00710       PRINT_ERROR("Cannot calculate the intersection points for the input curve and surface.\n");
00711       return CUBIT_FAILURE;
00712     }
00713   
00714   if (distShapeShape.Value() < get_sme_resabs_tolerance())
00715     {
00716       int numPnt = distShapeShape.NbSolution();
00717       for (int i = 1; i <= numPnt; i++)
00718     {
00719       gp_Pnt aPoint = distShapeShape.PointOnShape1(i);
00720      
00721       CubitVector cv(aPoint.X(), aPoint.Y(), aPoint.Z());
00722       intscts.append(cv);
00723     }
00724     }
00725  
00726   return CUBIT_SUCCESS;
00727 }
00728 
00729 //================================================================================
00730 // Description: Find extrema position on an entity list
00731 // Author     : Jane Hu
00732 // Date       : 10/30/07
00733 //================================================================================
00734 CubitStatus
00735 OCCQueryEngine::entity_extrema( DLIList<GeometryEntity*> &ref_entity_list,
00736                 const CubitVector *dir1,
00737                 const CubitVector *dir2,
00738                 const CubitVector *dir3,
00739                 CubitVector &extrema,
00740                 GeometryEntity *&extrema_entity_ptr )
00741 {
00742   //in OCC, the api_entity_extrema is used to calculate "possible
00743   //self-intersecting sweeping and to align lofting sections"
00744   PRINT_ERROR("There's no such call in OCC ");
00745   return CUBIT_FAILURE;
00746 }
00747 
00748 //================================================================================
00749 // Description: Find distance between two entities and closest positions.
00750 // Author     : Jane Hu
00751 // Date       : 10/19/07
00752 //================================================================================
00753 CubitStatus
00754 OCCQueryEngine::entity_entity_distance( GeometryEntity *entity1,
00755                                         GeometryEntity *entity2,
00756                                         CubitVector &pos1, CubitVector &pos2,
00757                                         double &distance )
00758 {
00759   TopoDS_Shape * shape1;
00760   TopoDS_Shape * shape2;
00761   if ((shape1 = get_TopoDS_Shape_of_entity(entity1)) == NULL)
00762     {
00763       PRINT_ERROR( "problem occured getting OCC entity.\n"
00764            "       Aborting.\n" );
00765       return CUBIT_FAILURE;
00766     }
00767 
00768   if( (shape2 = get_TopoDS_Shape_of_entity( entity2 )) == NULL )
00769     {
00770       PRINT_ERROR( "problem occured getting OCC entity.\n"
00771            "       Aborting.\n");
00772       return CUBIT_FAILURE;
00773     }
00774 
00775   BRepExtrema_DistShapeShape distShapeShape(*shape1, *shape2);
00776   //distShapeShape.Perform();
00777   
00778   if (!distShapeShape.IsDone())
00779     {
00780       PRINT_ERROR( "problem occured getting distance between OCC entities.\n"
00781            "       Aborting.\n");
00782       return CUBIT_FAILURE;
00783     }
00784 
00785   distance = distShapeShape.Value();
00786   gp_Pnt pnt1 = distShapeShape.PointOnShape1(1);
00787   gp_Pnt pnt2 = distShapeShape.PointOnShape2(1);
00788   pos1 = CubitVector(pnt1.X(), pnt1.Y(), pnt1.Z());
00789   pos2 = CubitVector(pnt2.X(), pnt2.Y(), pnt2.Z());
00790   return CUBIT_SUCCESS;
00791 }
00792 
00793 TopoDS_Shape* OCCQueryEngine::get_TopoDS_Shape_of_entity(TopologyBridge * entity_ptr)
00794 {
00795   if (OCCBody * occ_body = CAST_TO( entity_ptr, OCCBody))
00796     {
00797       TopoDS_Shape* theShape;
00798       occ_body->get_TopoDS_Shape(theShape);
00799       return theShape;
00800     }
00801 
00802   else if (OCCLump * lump_ptr = CAST_TO( entity_ptr,OCCLump))
00803     {
00804       TopoDS_Solid * theSolid = lump_ptr->get_TopoDS_Solid();
00805       if(theSolid)
00806     return (TopoDS_Shape*) theSolid; 
00807       else
00808     {
00809       PRINT_ERROR("OCCLump without TopoDS_Solid at %s:%d.\n", __FILE__, __LINE__ );
00810       return NULL;
00811     }
00812     }
00813 
00814   else if( OCCSurface * surface_ptr = CAST_TO( entity_ptr, OCCSurface))
00815     {
00816       TopoDS_Face *theFace = surface_ptr->get_TopoDS_Face();
00817       if(!theFace)
00818     {
00819       PRINT_ERROR("OCCSurface without TopoDS_Face at %s:%d.\n", __FILE__, __LINE__ );
00820       return NULL;
00821     }
00822 
00823       return (TopoDS_Shape*) theFace;
00824     }
00825 
00826   else if( OCCCurve * curve_ptr = CAST_TO( entity_ptr, OCCCurve))
00827     {
00828       TopoDS_Edge *theEdge = curve_ptr->get_TopoDS_Edge();
00829       if (!theEdge)
00830     {
00831       PRINT_ERROR("OCCCurve without TopoDS_Edge at %s:%d.\n", __FILE__, __LINE__ );
00832       return NULL;
00833     }
00834 
00835       return (TopoDS_Shape*) theEdge;
00836     }
00837 
00838   else if( OCCPoint * point_ptr = CAST_TO( entity_ptr, OCCPoint))
00839     {
00840       TopoDS_Vertex *thePoint = point_ptr->get_TopoDS_Vertex(); 
00841       if (!thePoint)
00842     {
00843       PRINT_ERROR("OCCPoint without TopoDS_Point at %s:%d.\n", __FILE__, __LINE__ );
00844       return NULL;
00845     }
00846 
00847       return (TopoDS_Shape*) thePoint;
00848     }
00849   
00850   PRINT_ERROR("Non-OCC TopologyBridge at %s:%d.\n", __FILE__, __LINE__ );
00851   return NULL;
00852 
00853 }
00854 //===========================================================================
00855 //Function Name: save_temp_geom_file
00856 //Member Type:  PUBLIC
00857 //Description:  function called for save/restore to save temporary FACET file
00858 //              If file is created, CubitString 'created_file' and
00859 //              'create_file_type' are set
00860 //Author:       Corey Ernst
00861 //Date:         1/18/2003
00862 //===========================================================================
00863 
00864 CubitStatus OCCQueryEngine::save_temp_geom_file( DLIList<TopologyBridge*>& ref_entity_list,
00865                          const char *file_name,
00866                          const CubitString &cubit_version,
00867                          CubitString &created_file,
00868                          CubitString &created_file_type)
00869 {
00870   int size_before = ref_entity_list.size();
00871   CubitString temp_filename(file_name);
00872   temp_filename += ".occ";
00873 
00874   ModelExportOptions M_O;
00875   if( export_solid_model( ref_entity_list, temp_filename.c_str(), OCC_TYPE,
00876                           cubit_version, M_O ) == CUBIT_FAILURE )
00877     {
00878       PRINT_ERROR( "Error occured while trying to save temporary OCC_BASED_GEOMETRY file\n");
00879       return CUBIT_FAILURE;
00880     }
00881 
00882   int size_after = ref_entity_list.size();
00883 
00884   if( size_before > size_after )
00885     {
00886       created_file +=  temp_filename;
00887       created_file_type += "OCC";
00888     }
00889   return CUBIT_SUCCESS;
00890 }
00891 
00892 //===========================================================================
00893 //Function Name:export_solid_model
00894 //Member Type:  PUBLIC
00895 //Description:  function called for save/restore to save temporary Brep file
00896 //Author:       Jane Hu
00897 //Date:         11/16/2007
00898 //===========================================================================
00899 
00900 CubitStatus OCCQueryEngine::export_solid_model( DLIList<TopologyBridge*>& ref_entity_list,
00901                         const char* file_name,
00902                         Model_File_Type file_type,
00903                         const CubitString &,
00904                         ModelExportOptions &)
00905 {
00906   if(  file_type != OCC_TYPE  && 
00907        file_type != STEP_TYPE &&
00908        file_type != IGES_TYPE)
00909     {
00910       //PRINT_ERROR("The specified file type, %s, is not supported!\n", filetype );
00911       return CUBIT_FAILURE;
00912     }
00913  
00914 /*
00915   char* name = "write.iges.unit";
00916   Standard_CString orig_unit;
00917   char* unit = "M";
00918   if(strcmp( file_type, "IGES") == 0 && unit != NULL)
00919   {
00920     orig_unit = Interface_Static::CVal(name);
00921     Interface_Static::SetCVal (name, unit); 
00922   }
00923 */
00924   DLIList<OCCBody*>    OCC_bodies;
00925   DLIList<OCCSurface*> OCC_surfaces;
00926   DLIList<OCCCurve*>   OCC_curves;
00927   DLIList<OCCPoint*>   OCC_points;
00928 
00929   DLIList<TopologyBridge*> ref_entities_handled;
00930 
00931   int i;
00932   //Collect all free entities (bodies, curves, vertices )
00933   ref_entity_list.reset();
00934   for(i=ref_entity_list.size(); i>0; i--)
00935     {
00936       TopologyBridge* ref_entity_ptr = ref_entity_list.get();
00937       CubitBoolean handled = CUBIT_TRUE;
00938 
00939       //if it is a Vertex
00940       if( OCCPoint* pt = CAST_TO( ref_entity_ptr, OCCPoint) )
00941     OCC_points.append( pt );
00942 
00943       //if it is a Curve
00944       else if( OCCCurve* curve = CAST_TO( ref_entity_ptr, OCCCurve) )
00945     OCC_curves.append( curve );
00946     
00947       //if it is a surface
00948       else if( OCCSurface* surf = CAST_TO( ref_entity_ptr, OCCSurface) )
00949     OCC_surfaces.append( surf );
00950    
00951       //if it is a Body
00952       else if( OCCBody* body = CAST_TO( ref_entity_ptr, OCCBody ) )
00953     OCC_bodies.append( body );
00954 
00955       else
00956     handled = CUBIT_FALSE;
00957 
00958       if( handled == CUBIT_TRUE )
00959     {
00960       ref_entities_handled.append( ref_entity_ptr );
00961       ref_entity_list.change_to(NULL);
00962     }
00963 
00964       ref_entity_list.step();
00965     }
00966 
00967   ref_entity_list.remove_all_with_value(NULL);
00968 
00969   int free_body_count = OCC_bodies.size();
00970   int free_curve_count = OCC_curves.size();
00971   int free_point_count = OCC_points.size();
00972   int free_surface_count = OCC_surfaces.size();
00973 
00974   //if nothing to write out...return
00975   if( free_body_count == 0 && free_surface_count == 0 && 
00976       free_curve_count == 0 && free_point_count == 0)
00977     return CUBIT_SUCCESS;
00978 
00979   //save the facets (geometry info )
00980   CubitStatus status;
00981 
00982   //write out topology and attributes
00983   status = write_topology( file_name, file_type,
00984                            OCC_bodies, OCC_surfaces,
00985                            OCC_curves, OCC_points );
00986 /*
00987   //set the unit back.
00988   if(strcmp( file_type, "IGES") == 0 && unit != NULL) 
00989     Interface_Static::SetCVal (name,orig_unit);
00990 */
00991   if( status == CUBIT_FAILURE ) return CUBIT_FAILURE;
00992 
00993   if( free_body_count || free_surface_count || 
00994       free_curve_count || free_point_count )
00995     PRINT_INFO( "\nExported:" );
00996 
00997   int flg = 0;
00998 
00999   if( free_body_count )
01000     {
01001       if( flg )PRINT_INFO( "         " );else flg=1;
01002       if( free_body_count == 1 )
01003          PRINT_INFO( "%4d OCC Body to %s\n", free_body_count, file_name );
01004       else
01005          PRINT_INFO( "%4d OCC Bodies to %s\n", free_body_count, file_name );
01006     }
01007 
01008   if( free_surface_count )
01009     {
01010       if( flg )PRINT_INFO( "         " );else flg=1;
01011       if( free_surface_count == 1 )
01012     PRINT_INFO( "%4d OCC Surface to %s\n", free_surface_count, file_name );
01013       else
01014     PRINT_INFO( "%4d OCC Surface to %s\n", free_surface_count, file_name );
01015     }
01016 
01017   if( free_curve_count )
01018     {
01019       if( flg )PRINT_INFO( "         " );else flg=1;
01020       if( free_curve_count == 1 )
01021     PRINT_INFO( "%4d OCC Curve to %s\n", free_curve_count, file_name );
01022       else
01023     PRINT_INFO( "%4d OCC Curves to %s\n", free_curve_count, file_name );
01024     }
01025 
01026   if( free_point_count )
01027     {
01028       if( flg )PRINT_INFO( "         " );else flg=1;
01029       if( free_point_count == 1 )
01030     PRINT_INFO( "%4d OCC Point to %s\n", free_point_count, file_name );
01031       else
01032     PRINT_INFO( "%4d OCC Points to %s\n", free_point_count, file_name );
01033     }
01034   PRINT_INFO( "\n" );
01035 
01036   return CUBIT_SUCCESS;
01037 }
01038 
01039 CubitStatus OCCQueryEngine::export_solid_model( DLIList<TopologyBridge*>& ref_entity_list,
01040                         char*& p_buffer,
01041                         int& n_buffer_size,
01042                         bool b_export_buffer)
01043 {
01044   DLIList<OCCBody*>    OCC_bodies;
01045   DLIList<OCCSurface*> OCC_surfaces;
01046   DLIList<OCCCurve*>   OCC_curves;
01047   DLIList<OCCPoint*>   OCC_points;
01048 
01049   DLIList<TopologyBridge*> ref_entities_handled;
01050 
01051   int i;
01052   //Collect all free entities (bodies, curves, vertices )
01053   ref_entity_list.reset();
01054   for(i=ref_entity_list.size(); i>0; i--)
01055     {
01056       TopologyBridge* ref_entity_ptr = ref_entity_list.get();
01057       CubitBoolean handled = CUBIT_TRUE;
01058 
01059       //if it is a Vertex
01060       if( OCCPoint* pt = CAST_TO( ref_entity_ptr, OCCPoint) )
01061     OCC_points.append( pt );
01062 
01063       //if it is a Curve
01064       else if( OCCCurve* curve = CAST_TO( ref_entity_ptr, OCCCurve) )
01065     OCC_curves.append( curve );
01066     
01067       //if it is a surface
01068       else if( OCCSurface* surf = CAST_TO( ref_entity_ptr, OCCSurface) )
01069     OCC_surfaces.append( surf );
01070    
01071       //if it is a Body
01072       else if( OCCBody* body = CAST_TO( ref_entity_ptr, OCCBody ) )
01073     OCC_bodies.append( body );
01074 
01075       else
01076     handled = CUBIT_FALSE;
01077 
01078       if( handled == CUBIT_TRUE )
01079     {
01080       ref_entities_handled.append( ref_entity_ptr );
01081       ref_entity_list.change_to(NULL);
01082     }
01083 
01084       ref_entity_list.step();
01085     }
01086 
01087   ref_entity_list.remove_all_with_value(NULL);
01088 
01089   int free_body_count = OCC_bodies.size();
01090   int free_curve_count = OCC_curves.size();
01091   int free_point_count = OCC_points.size();
01092   int free_surface_count = OCC_surfaces.size();
01093 
01094   //if nothing to write out...return
01095   if( free_body_count == 0 && free_surface_count == 0 && 
01096       free_curve_count == 0 && free_point_count == 0)
01097     return CUBIT_SUCCESS;
01098 
01099   //save the facets (geometry info )
01100   CubitStatus status;
01101 
01102   //write out topology and attributes
01103   status = write_topology( p_buffer, n_buffer_size,
01104                b_export_buffer,
01105                OCC_bodies, OCC_surfaces,
01106                OCC_curves, OCC_points);
01107   if( status == CUBIT_FAILURE ) return CUBIT_FAILURE;
01108 
01109   if( free_body_count || free_surface_count || 
01110       free_curve_count || free_point_count )
01111   {
01112     if (b_export_buffer) PRINT_INFO( "\nExported:" );
01113     else PRINT_INFO( "\nSize checked:" );
01114   }
01115   int flg = 0;
01116 
01117   if( free_body_count )
01118     {
01119       if( flg )PRINT_INFO( "         " );else flg=1;
01120       if( free_body_count == 1 )
01121          PRINT_INFO( "%4d OCC Body to buffer\n", free_body_count );
01122       else
01123          PRINT_INFO( "%4d OCC Bodies to buffer\n", free_body_count );
01124     }
01125 
01126   if( free_surface_count )
01127     {
01128       if( flg )PRINT_INFO( "         " );else flg=1;
01129       if( free_surface_count == 1 )
01130     PRINT_INFO( "%4d OCC Surface to buffer\n", free_surface_count );
01131       else
01132     PRINT_INFO( "%4d OCC Surface to buffer\n", free_surface_count );
01133     }
01134 
01135   if( free_curve_count )
01136     {
01137       if( flg )PRINT_INFO( "         " );else flg=1;
01138       if( free_curve_count == 1 )
01139     PRINT_INFO( "%4d OCC Curve to buffer\n", free_curve_count );
01140       else
01141     PRINT_INFO( "%4d OCC Curves to buffer\n", free_curve_count );
01142     }
01143 
01144   if( free_point_count )
01145     {
01146       if( flg )PRINT_INFO( "         " );else flg=1;
01147       if( free_point_count == 1 )
01148     PRINT_INFO( "%4d OCC Point to buffer\n", free_point_count );
01149       else
01150     PRINT_INFO( "%4d OCC Points to buffer\n", free_point_count );
01151     }
01152   PRINT_INFO( "\n" );
01153 
01154   return CUBIT_SUCCESS;
01155 }
01156 
01157 void OCCQueryEngine::body_attributes_for_writing(DLIList<OCCBody*> &OCC_bodies,
01158                                   BRep_Builder &B,
01159                                   TopoDS_Compound &Co,
01160                                   DLIList<OCCLump*> &single_lumps,
01161                                   DLIList< DLIList<CubitSimpleAttrib>*> &lists)
01162 {
01163   //Add every shape to the compound
01164   OCCLump* lump = NULL;
01165   DLIList<CubitSimpleAttrib> body_csa_list;
01166 
01167   for (int i = 0; i < OCC_bodies.size(); i++)
01168   {
01169     OCCBody* body = OCC_bodies.get_and_step();
01170     TopoDS_Compound *shape = body->get_TopoDS_Shape();
01171     if (shape == NULL || shape->IsNull()) //single lump or sheet or shell body
01172     {
01173        DLIList<OCCSurface*> surfaces = body->my_sheet_surfaces();
01174        DLIList<OCCShell*> shells = body->shells();
01175        DLIList<Lump*> lumps = body->lumps();
01176        if(surfaces.size() == 1)
01177          B.Add(Co,*(surfaces.get()->get_TopoDS_Face()));
01178        else if (shells.size() == 1)
01179          B.Add(Co,*(shells.get()->get_TopoDS_Shell()));
01180        else
01181        {
01182          lump = CAST_TO(lumps.get(), OCCLump);
01183          B.Add(Co, *(lump->get_TopoDS_Solid()));
01184          //if body has attributes, add them to the solid.
01185          DLIList<CubitSimpleAttrib> csa_list;
01186          body->get_simple_attribute(csa_list);
01187          body_csa_list.clean_out();
01188          for(int i = 0; i < csa_list.size(); i++)
01189          {
01190            CubitSimpleAttrib body_csa = csa_list.get_and_step();
01191            CubitString pre_fix("#SINGLELUMP%");
01192            pre_fix += CubitString::number(i);
01193 
01194            body_csa.string_data_list().insert(body_csa.string_data_list().begin(), pre_fix);
01195            lump->append_simple_attribute_virt(body_csa);
01196            body_csa_list.append(body_csa);
01197          }
01198          if(csa_list.size() > 0)
01199          {
01200            single_lumps.append(lump);
01201            lists.append(new DLIList<CubitSimpleAttrib>(body_csa_list));
01202          }
01203        }
01204        continue;
01205     }
01206     B.Add(Co, *shape);
01207   }
01208 } 
01209 //===========================================================================
01210 //Function Name:write_topology
01211 //Member Type:  PUBLIC
01212 //Description:  function called for write out temporary Brep file
01213 //Author:       Jane Hu
01214 //Date:         11/16/2007
01215 //===========================================================================
01216 
01217 CubitStatus
01218 OCCQueryEngine::write_topology( const char* file_name,
01219                                 Model_File_Type file_type,
01220                                 DLIList<OCCBody*> &OCC_bodies,
01221                                 DLIList<OCCSurface*> &OCC_surfaces,
01222                                 DLIList<OCCCurve*> &OCC_curves,
01223                                 DLIList<OCCPoint*> &OCC_points )
01224 {
01225 
01226   int i;
01227   //Create a compound shape to export
01228   BRep_Builder B;
01229   TopoDS_Compound Co;
01230   B.MakeCompound(Co);
01231 
01232   //Add every shape to the compound
01233   DLIList<OCCLump*> single_lumps;
01234   DLIList< DLIList<CubitSimpleAttrib>*> lists;
01235   OCCLump* lump = NULL;
01236 
01237   if(OCC_bodies.size() > 0)
01238     body_attributes_for_writing(OCC_bodies, B, Co, single_lumps, lists);
01239 
01240   for (i = 0; i < OCC_surfaces.size(); i++)
01241     {
01242       TopoDS_Face *face = OCC_surfaces.get_and_step()->get_TopoDS_Face();
01243       B.Add(Co, *face);
01244     }
01245 
01246   //Add standalone wires to the export BRep file
01247   for (i = 0; i < WireList->size(); i++)
01248     {
01249       TopoDS_Wire *wire = WireList->get_and_step()->get_TopoDS_Wire();
01250       B.Add(Co, *wire);
01251     }
01252 
01253   for (i = 0; i < OCC_curves.size(); i++)
01254     {
01255       TopoDS_Edge *edge = OCC_curves.get_and_step()->get_TopoDS_Edge();
01256       B.Add(Co, *edge);
01257     }
01258 
01259   for (i = 0; i < OCC_points.size(); i++)
01260     {
01261       TopoDS_Vertex *vertex = OCC_points.get_and_step()->get_TopoDS_Vertex();
01262       B.Add(Co, *vertex);
01263     }
01264  
01265   if(file_type == OCC_TYPE)
01266   {
01267     TDF_Label label;
01268     if(EXPORT_ATTRIB)
01269       label = mainLabel;
01270 
01271     CubitBoolean result = Write(Co, const_cast<char*>(file_name),label);
01272     //remove the body attributes from lump
01273     for (int i = 0; i < single_lumps.size(); i++)
01274     {
01275       lump = single_lumps.get_and_step();
01276       DLIList<CubitSimpleAttrib>* p_csas = lists.get_and_step();
01277       for(int j = 0 ; j < p_csas->size(); j ++)
01278       {
01279         const CubitSimpleAttrib& csa = p_csas->get_and_step();
01280         lump->remove_simple_attribute_virt(csa);  
01281       }
01282       delete p_csas;
01283     }
01284     if(!result)
01285       return CUBIT_FAILURE;
01286   } 
01287 
01288 #ifdef HAVE_OCC_STEP
01289   else if(file_type == STEP_TYPE)
01290   {
01291     STEPControl_Writer writer;
01292     writer.Model( Standard_True);
01293     writer.Transfer(Co, STEPControl_AsIs );
01294     IFSelect_ReturnStatus stat = writer.Write( (char*) file_name);
01295     if (stat  != IFSelect_RetDone)
01296     {
01297        PRINT_INFO("%s: Cannot open file", file_name );
01298        return CUBIT_FAILURE;
01299     }
01300   }
01301 #endif
01302 #ifdef HAVE_OCC_IGES
01303  else if (file_type == IGES_TYPE) // IGES file
01304   {
01305     IGESControl_Writer writer;
01306     writer.AddShape(Co);
01307     writer.ComputeModel();
01308     Standard_Boolean  stat = writer.Write( (char*) file_name);
01309     if (!stat )
01310     {
01311        PRINT_INFO("%s: Cannot open file", file_name );
01312        return CUBIT_FAILURE;
01313     }
01314   }
01315 #endif
01316   else {
01317     PRINT_ERROR("File formats other than OCC, STEP and IGES are  not supported by OCC.\n");
01318     return CUBIT_FAILURE;
01319   }
01320 
01321   return CUBIT_SUCCESS;
01322 }
01323 
01324 CubitStatus
01325 OCCQueryEngine::write_topology( char*& p_buffer,
01326                 int& n_buffer_size,
01327                 bool b_export_buffer,
01328                 DLIList<OCCBody*> &OCC_bodies,
01329                 DLIList<OCCSurface*> &OCC_surfaces,
01330                 DLIList<OCCCurve*> &OCC_curves,
01331                 DLIList<OCCPoint*> &OCC_points)
01332 {
01333 
01334   int i;
01335   //Create a compound shape to export
01336   BRep_Builder B;
01337   TopoDS_Compound Co;
01338   B.MakeCompound(Co);
01339 
01340   //Add every shape to the compound
01341   DLIList<OCCLump*> single_lumps;
01342   DLIList< DLIList<CubitSimpleAttrib>*> lists;
01343   OCCLump* lump = NULL;
01344 
01345   if(OCC_bodies.size() > 0)
01346     body_attributes_for_writing(OCC_bodies, B, Co, single_lumps, lists);
01347 
01348   for (i = 0; i < OCC_surfaces.size(); i++)
01349     {
01350       TopoDS_Face *face = OCC_surfaces.get_and_step()->get_TopoDS_Face();
01351       B.Add(Co, *face);
01352     }
01353 
01354   //Add standalone wires to the export BRep file
01355   for (i = 0; i < WireList->size(); i++)
01356     {
01357       TopoDS_Wire *wire = WireList->get_and_step()->get_TopoDS_Wire();
01358       B.Add(Co, *wire);
01359     }
01360 
01361   for (i = 0; i < OCC_curves.size(); i++)
01362     {
01363       TopoDS_Edge *edge = OCC_curves.get_and_step()->get_TopoDS_Edge();
01364       B.Add(Co, *edge);
01365     }
01366 
01367   for (i = 0; i < OCC_points.size(); i++)
01368     {
01369       TopoDS_Vertex *vertex = OCC_points.get_and_step()->get_TopoDS_Vertex();
01370       B.Add(Co, *vertex);
01371     }
01372  
01373   //if(strcmp(file_type, "OCC") == 0)
01374   //{
01375     TDF_Label label;
01376     if(EXPORT_ATTRIB)
01377       label = mainLabel;
01378 
01379     if(!Write(Co, p_buffer, n_buffer_size, b_export_buffer, label))
01380       return CUBIT_FAILURE;
01381 
01382     //remove the body attributes from lump
01383     for (int i = 0; i < single_lumps.size(); i++)
01384     {
01385       lump = single_lumps.get_and_step();
01386       DLIList<CubitSimpleAttrib>* p_csas = lists.get_and_step();
01387       for(int j = 0 ; j < p_csas->size(); j ++)
01388       {
01389         const CubitSimpleAttrib& csa = p_csas->get_and_step();
01390         lump->remove_simple_attribute_virt(csa);
01391       }
01392       delete p_csas;
01393     }
01394 
01395   return CUBIT_SUCCESS;
01396 }
01397 
01398 CubitBoolean OCCQueryEngine::Write(const TopoDS_Shape& Sh,
01399                                    const Standard_CString File,
01400                                    TDF_Label label) 
01401 {
01402   ofstream os;
01403   os.open(File, ios::out);
01404   if (!os.rdbuf()->is_open()) return Standard_False;
01405   
01406   CubitBoolean isGood = (os.good() && !os.eof());
01407   if(!isGood)
01408     return isGood;
01409 
01410   OCCShapeAttributeSet SS;
01411   SS.Add(Sh);
01412 
01413   os << "DBRep_DrawableShape\n";  // for easy Draw read
01414   SS.Write(os);
01415   isGood = os.good();
01416   if(isGood )
01417     SS.Write(Sh,os,&label);
01418   os.flush();
01419   isGood = os.good();
01420   os.close();
01421   isGood = os.good() && isGood;
01422 
01423   return isGood;
01424 }
01425 
01426 CubitBoolean OCCQueryEngine::Write(const TopoDS_Shape& Sh,
01427                    char*& pBuffer,
01428                    int& n_buffer_size,
01429                    bool b_write_buffer,
01430                                    TDF_Label label)
01431 {
01432   // make buffer as ouput stream
01433   std::stringbuf sb;
01434   std::iostream os(&sb);
01435   OCCShapeAttributeSet SS;
01436   
01437   // write to output stream
01438   SS.Add(Sh);
01439   os << "DBRep_DrawableShape\n";  // for easy Draw read
01440   SS.Write(os);
01441   CubitBoolean isGood = os.good();
01442   if (!isGood) return isGood;
01443   SS.Write(Sh,os,&label);
01444   isGood = os.good();
01445   if (!isGood) return isGood;
01446   
01447   n_buffer_size = os.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios::out);
01448 
01449   // get real geometries from output stream to buffer
01450   if (b_write_buffer) os.read(pBuffer, n_buffer_size);
01451   
01452   return CUBIT_TRUE;
01453 }
01454                                    
01455 CubitBoolean OCCQueryEngine::Read(TopoDS_Shape& Sh,
01456                                   const Standard_CString File,
01457                                   TDF_Label label)
01458 {
01459   ifstream in( File );
01460   if (in.fail()) {
01461     PRINT_INFO("%s: Cannot open file", File );
01462     return CUBIT_FAILURE;
01463   }
01464 
01465   OCCShapeAttributeSet SS;
01466   SS.Read(in, CUBIT_TRUE);
01467   int nbshapes = SS.NbShapes();
01468   if(!nbshapes) return CUBIT_FALSE;
01469   SS.Read(Sh,in,nbshapes, &label);
01470   return CUBIT_TRUE;
01471 }
01472                                    
01473 CubitBoolean OCCQueryEngine::Read(TopoDS_Shape& Sh,
01474                   const char* pBuffer,
01475                   const int n_buffer_size,
01476                                   TDF_Label label)
01477 {
01478   // make buffer as input stream
01479   std::stringbuf sb;
01480   std::iostream is(&sb);
01481   is.write(pBuffer, n_buffer_size);
01482   
01483   // read from input stream
01484   OCCShapeAttributeSet SS;
01485   SS.Read(is, false);
01486   int nbshapes = SS.NbShapes();
01487   if (!nbshapes) return CUBIT_FALSE;
01488   SS.Read(Sh, is, nbshapes, &label);
01489 
01490   return CUBIT_TRUE;
01491 }
01492 
01493 CubitStatus
01494 OCCQueryEngine::import_temp_geom_file(FILE* file_ptr,
01495                                       const char* file_name,
01496                                       Model_File_Type file_type,
01497                                       DLIList<TopologyBridge*> &bridge_list )
01498 {
01499   ModelImportOptions M_O;
01500   return import_solid_model( file_name, file_type, bridge_list, M_O );
01501 }
01502 
01503 //===========================================================================
01504 //Function Name:import_solid_model
01505 //Member Type:  PUBLIC
01506 //Description:  function called for read in temporary Brep file
01507 //Author:       Jane Hu
01508 //Date:         11/16/2007
01509 //===========================================================================
01510 
01511 CubitStatus OCCQueryEngine::import_solid_model(
01512                            const char* file_name ,
01513                            Model_File_Type file_type,
01514                            DLIList<TopologyBridge*> &imported_entities,
01515                                                ModelImportOptions &import_options)
01516 {
01517   TopoDS_Shape *aShape = new TopoDS_Shape;
01518   
01519   //BRep_Builder aBuilder;
01520   if(file_type == OCC_TYPE)
01521   {
01522     Standard_Boolean result = Read(*aShape, (char*) file_name, mainLabel);
01523     if (result==0) return CUBIT_FAILURE;
01524   }
01525 #ifdef HAVE_OCC_STEP 
01526   else if (file_type == STEP_TYPE)
01527   {
01528     STEPControl_Reader reader;
01529 /*
01530     char* name = "xstep.cascade.unit";
01531     char* unit = "M"; 
01532     Standard_CString orig_unit = Interface_Static::CVal(name);
01533     Interface_Static::SetCVal (name, unit); //this set is good for both step
01534                                             // and iges files.
01535 */
01536     IFSelect_ReturnStatus stat = reader.ReadFile( (char*) file_name);
01537 /*
01538     //set the unit back.
01539     Interface_Static::SetCVal (name,orig_unit);
01540 */
01541     if (stat  != IFSelect_RetDone)
01542     {
01543        PRINT_INFO("%s: Cannot open file", file_name );
01544        return CUBIT_FAILURE;
01545     } 
01546     reader.TransferRoots();
01547     *aShape = reader.OneShape(); 
01548   }
01549 #endif
01550 #ifdef HAVE_OCC_IGES
01551   else if(file_type == IGES_TYPE)
01552   {
01553     IGESControl_Reader reader;
01554 /*
01555     char* name = "xstep.cascade.unit";
01556     char* unit = "M";
01557     Interface_Static::SetCVal (name, unit); //this set is good for both step
01558                                             // and iges files.
01559 */
01560     const Standard_CString string1 = file_name;
01561     IFSelect_ReturnStatus stat = reader.ReadFile( string1);
01562 
01563 //    Interface_Static::SetCVal (name, "MM");
01564 
01565     if (stat  != IFSelect_RetDone)
01566     {
01567        PRINT_INFO("%s: Cannot open file", file_name );
01568        return CUBIT_FAILURE;
01569     } 
01570     reader.TransferRoots(); 
01571     *aShape = reader.OneShape();
01572   } 
01573 #endif
01574   else 
01575   {
01576     PRINT_ERROR("File formats other than OCC, STEP and IGES are not supported by OCC\n");
01577     return CUBIT_FAILURE;
01578   }
01579     
01580   //All read in shapes are wrapped inside a compound shape. Ignore this one
01581   TopoDS_Iterator it(*aShape);
01582   if(aShape->ShapeType() != TopAbs_COMPOUND)
01583   {
01584     imported_entities += populate_topology_bridge(*aShape);
01585     return CUBIT_SUCCESS;
01586   }
01587 
01588   for(;it.More();it.Next())
01589   {
01590     TopoDS_Shape shape = it.Value();
01591     imported_entities += populate_topology_bridge(shape);
01592   }
01593 
01594   return CUBIT_SUCCESS;
01595 }
01596 
01597 CubitStatus OCCQueryEngine::import_solid_model(DLIList<TopologyBridge*> &imported_entities,
01598                            const char* pBuffer,
01599                            const int n_buffer_size)
01600 {
01601   TopoDS_Shape *aShape = new TopoDS_Shape;
01602   Standard_Boolean result = Read(*aShape, pBuffer, n_buffer_size, mainLabel);
01603   if (result==0) return CUBIT_FAILURE;
01604   
01605   //All read in shapes are wrapped inside a compound shape. Ignore this one
01606   TopoDS_Iterator it(*aShape);
01607   if(aShape->ShapeType() != TopAbs_COMPOUND)
01608   {
01609     imported_entities += populate_topology_bridge(*aShape);
01610     return CUBIT_SUCCESS;
01611   }
01612 
01613   for(;it.More();it.Next())
01614   {
01615     TopoDS_Shape shape = it.Value();
01616     imported_entities += populate_topology_bridge(shape);
01617   }
01618 
01619   return CUBIT_SUCCESS;
01620 }
01621 
01622 //===========================================================================
01623 //Function Name:populate_topology_bridge
01624 //Member Type:  PUBLIC
01625 //Description:  function called for populating topology bridge for OCC entity 
01626 //Author:       Jane Hu
01627 //Date:         11/16/2007
01628 //===========================================================================
01629 
01630 DLIList<TopologyBridge*> OCCQueryEngine::populate_topology_bridge(TopoDS_Shape& aShape)
01631 {
01632   DLIList<TopologyBridge*> tblist;
01633   // suitable to populate for a  TopoDS_Compound shape.
01634   if ( aShape.ShapeType() == TopAbs_COMPOUND)
01635     tblist.append(populate_topology_bridge(TopoDS::Compound(aShape)));
01636 
01637   else if(aShape.ShapeType() == TopAbs_SOLID)
01638   {
01639     Lump *lump = 
01640     populate_topology_bridge(TopoDS::Solid(aShape), CUBIT_TRUE);
01641     tblist.append(CAST_TO(lump, OCCLump)->get_body());
01642   }
01643 
01644   else if(aShape.ShapeType() == TopAbs_SHELL)
01645   {
01646     OCCShell* shell =
01647        populate_topology_bridge(TopoDS::Shell(aShape), CUBIT_TRUE);
01648     tblist.append(shell->my_body());
01649   }
01650 
01651   else if(aShape.ShapeType() == TopAbs_FACE)
01652   {
01653     Surface* face =
01654       populate_topology_bridge(TopoDS::Face(aShape), CUBIT_TRUE);
01655     if(face)
01656       tblist.append(CAST_TO(face, OCCSurface)->my_body());
01657   }
01658 
01659   else if(aShape.ShapeType() == TopAbs_WIRE)
01660     populate_topology_bridge(TopoDS::Wire(aShape), CUBIT_TRUE);
01661 
01662   else if(aShape.ShapeType() == TopAbs_EDGE)
01663     tblist.append(populate_topology_bridge(TopoDS::Edge(aShape),CUBIT_TRUE));
01664 
01665   else if(aShape.ShapeType() == TopAbs_VERTEX)
01666     tblist.append(populate_topology_bridge(TopoDS::Vertex(aShape), CUBIT_TRUE));
01667   else
01668     PRINT_ERROR("Wrong topology type is given. \n");
01669   tblist.remove_all_with_value(NULL);
01670   return tblist;
01671 }
01672 
01673 BodySM* OCCQueryEngine::populate_topology_bridge(const TopoDS_Compound& aShape)
01674 {
01675   if(aShape.IsNull())
01676     return (BodySM*)NULL;
01677   OCCBody *body = (OCCBody*)NULL;
01678   if (!OCCMap->IsBound(aShape) || 
01679        OccToCGM->find(OCCMap->Find(aShape)) == OccToCGM->end())
01680     {
01681       //check to see if this compound has only one lump which is already in 
01682       //in another body. Unite operation will return a one lump compound.
01683       //Check also if this compound has only shells. which is or has faces that
01684       //are already in another body. Unite faces will return such shell.
01685       TopExp_Explorer Ex;
01686       int num_lumps = 0, num_shells = 0, num_faces = 0;
01687       TopoDS_Solid solid;
01688       for (Ex.Init(aShape, TopAbs_SOLID); Ex.More(); Ex.Next()) 
01689       {
01690         num_lumps++;
01691         solid = TopoDS::Solid(Ex.Current());
01692       }
01693 
01694       TopoDS_Shell shell;
01695       for (Ex.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); Ex.More(); Ex.Next())
01696       {
01697         num_shells++;
01698         shell = TopoDS::Shell(Ex.Current());
01699       }
01700 
01701       TopoDS_Face face;
01702       for (Ex.Init(aShape, TopAbs_FACE, TopAbs_SHELL);  Ex.More(); Ex.Next())
01703       {
01704         num_faces++;
01705         face = TopoDS::Face(Ex.Current());
01706       }
01707 
01708       if(num_faces + num_shells + num_lumps == 1)
01709       {
01710         if (num_faces  == 1 && (!OCCMap->IsBound(face) ||
01711                       OccToCGM->find(OCCMap->Find(face)) == OccToCGM->end()))
01712         {
01713           Surface* surface = populate_topology_bridge(face, CUBIT_TRUE);
01714           return CAST_TO(surface, OCCSurface)->my_body();
01715         }
01716         else if (num_shells == 1 && (!OCCMap->IsBound(shell)||
01717                   OccToCGM->find(OCCMap->Find(shell)) == OccToCGM->end()))
01718         {
01719           OCCShell* occ_shell = populate_topology_bridge(shell, CUBIT_TRUE);
01720           return occ_shell->my_body();
01721         }
01722         else if( num_lumps == 1 && (!OCCMap->IsBound(solid) ||
01723                   OccToCGM->find(OCCMap->Find(solid)) == OccToCGM->end()))
01724         {
01725           Lump* lump= populate_topology_bridge(solid, CUBIT_TRUE);
01726           return CAST_TO(lump, OCCLump)->get_body();
01727         }
01728         else //find existing body
01729         {
01730           int k;
01731           if(num_lumps == 1)
01732           {
01733             k = OCCMap->Find(solid);
01734             OCCLump* lump = (OCCLump*)(OccToCGM->find(k))->second;
01735             body = CAST_TO(lump->get_body(), OCCBody);
01736           }
01737           else if (num_shells == 1)
01738           {
01739             k = OCCMap->Find(shell);
01740             OCCShell* occ_shell = (OCCShell*)(OccToCGM->find(k))->second;
01741             body = occ_shell->my_body();
01742           }
01743           else
01744           {
01745             k = OCCMap->Find(face);
01746             OCCSurface* occ_surface = (OCCSurface*) (OccToCGM->find(k))->second;
01747             body = occ_surface->my_body();
01748           }
01749         }
01750       } 
01751 
01752       else
01753       {
01754         TopoDS_Compound *comsolid = new TopoDS_Compound;
01755         *comsolid = aShape;
01756         body = new OCCBody(comsolid);
01757         int current_id;
01758         if(!OCCMap->IsBound(aShape))
01759         {
01760           iTotalTBCreated++;
01761           current_id = iTotalTBCreated;
01762           OCCMap->Bind(aShape, current_id);
01763         }
01764 
01765         else
01766           current_id = OCCMap->Find(aShape);
01767 
01768         OccToCGM->insert(valType(current_id,
01769                              (TopologyBridge*)body));
01770         BodyList->append(body);
01771       }
01772     }
01773     else
01774     {
01775       int k = OCCMap->Find(aShape);
01776       body = (OCCBody*)(OccToCGM->find(k))->second;
01777       TopoDS_Compound compound = aShape;
01778       body->set_TopoDS_Shape(compound);
01779     }
01780 
01781   TopExp_Explorer Ex;
01782   DLIList<Lump*> lumps;
01783   for (Ex.Init(aShape, TopAbs_SOLID); Ex.More(); Ex.Next())
01784   {
01785      TopoDS_Shape sh = Ex.Current();
01786      Lump* lump = populate_topology_bridge(TopoDS::Solid(sh));
01787      lumps.append(lump);
01788      CAST_TO(lump, OCCLump)->add_body(body);
01789      //add the solid shape into map
01790      TopoDS_Shape parent = aShape;
01791      int current_id;
01792      add_shape_to_map(sh, parent, current_id);
01793      if(!OCCMap->IsBound(sh) ||
01794         OccToCGM->find(OCCMap->Find(sh)) == OccToCGM->end())
01795         OccToCGM->insert(valType(current_id, (TopologyBridge*)lump));
01796   }
01797   body->lumps(lumps);
01798 
01799   DLIList<OCCShell*> shells;
01800   for (Ex.Init(aShape, TopAbs_SHELL, TopAbs_SOLID);Ex.More(); Ex.Next())
01801   {
01802     TopoDS_Shape sh = Ex.Current();
01803     OCCShell * shell = populate_topology_bridge(TopoDS::Shell(sh)); 
01804     OCCLump* lump = shell->my_lump();
01805     if(lump == (OCCLump*)NULL)
01806       lump = new OCCLump(NULL, NULL, shell);
01807     lumps.append(lump);
01808     lump->add_body(body);
01809     shell->set_body(body);
01810     shell->set_lump(lump);  
01811     shells.append(shell);
01812     TopoDS_Shape parent = aShape;
01813     int current_id;
01814     add_shape_to_map(sh, parent, current_id);
01815     if(!OCCMap->IsBound(sh) ||
01816      OccToCGM->find(OCCMap->Find(sh)) == OccToCGM->end())
01817        OccToCGM->insert(valType(current_id, (TopologyBridge*)shell));
01818   }
01819   body->shells(shells);
01820   
01821   DLIList<OCCSurface*> surfaces;
01822   for (Ex.Init(aShape, TopAbs_FACE, TopAbs_SHELL);Ex.More(); Ex.Next())
01823   {
01824     TopoDS_Shape sh = Ex.Current();
01825     Surface* face = populate_topology_bridge(TopoDS::Face(sh));
01826     OCCSurface *surface = CAST_TO(face, OCCSurface);
01827     OCCShell* shell = surface->my_shell();
01828     if (shell == (OCCShell*) NULL)
01829       shell = new OCCShell(NULL, surface);
01830     OCCLump* lump = surface->my_lump();
01831     if(lump == (OCCLump*) NULL)
01832       lump = new OCCLump(NULL, surface);
01833     lumps.append(lump);
01834     lump->add_body(body);
01835     surface->set_body(body);
01836     surface->set_lump(lump);
01837     surface->set_shell(shell);
01838     shell->set_body(body);
01839     shell->set_lump(lump);
01840     TopoDS_Shape parent = aShape;
01841     surfaces.append(surface);
01842     int current_id;
01843     add_shape_to_map(sh, parent, current_id);
01844     if(!OCCMap->IsBound(sh) ||
01845      OccToCGM->find(OCCMap->Find(sh)) == OccToCGM->end())
01846        OccToCGM->insert(valType(current_id, (TopologyBridge*)face));
01847 
01848   } 
01849   body->set_sheet_surfaces(surfaces);
01850   return body;
01851 }
01852 
01853 Lump* OCCQueryEngine::populate_topology_bridge(const TopoDS_Solid& aShape,
01854                            CubitBoolean build_body)
01855 {
01856   if(aShape.IsNull())
01857     return (Lump*)NULL;
01858 
01859   OCCLump *lump = NULL;
01860   OCCBody *body = NULL;
01861   int current_lump_number = 0;
01862   if (!OCCMap->IsBound(aShape) || 
01863       OccToCGM->find(OCCMap->Find(aShape)) == OccToCGM->end())
01864   {
01865     TopoDS_Solid *posolid =  new TopoDS_Solid;
01866     *posolid = aShape;
01867     lump = new OCCLump(posolid);
01868     if (build_body)
01869     {
01870       if(OCCMap->IsBound(aShape))
01871         current_lump_number = OCCMap->Find(aShape);
01872       else
01873       {
01874         iTotalTBCreated++;
01875         current_lump_number = iTotalTBCreated;
01876       }
01877       body = new OCCBody(NULL, NULL, NULL, lump);
01878       DLIList<CubitSimpleAttrib> csa_list;
01879       lump->get_simple_attribute(csa_list);
01880       //if there's body attribute, append it to body and delete it from lump.
01881       for(int i = 0; i < csa_list.size(); i++)
01882       {
01883         const CubitSimpleAttrib& csa = csa_list.get_and_step();
01884         CubitString type = csa.string_data_list()[0];
01885         CubitString subtype = type.substr(0,12);
01886         if(subtype == "#SINGLELUMP%")
01887         {  
01888           lump->remove_simple_attribute_virt(csa);
01889           CubitSimpleAttrib copy = csa;
01890           copy.string_data_list().erase(copy.string_data_list().begin());
01891           body->append_simple_attribute_virt(copy);
01892         }
01893       }
01894       BodyList->append(body);
01895       lump->add_body(body);
01896     }
01897   }
01898   else 
01899   {
01900     int k = OCCMap->Find(aShape);
01901     lump = (OCCLump*)(OccToCGM->find(k))->second;
01902     lump->set_TopoDS_Solid(aShape);
01903     body = static_cast<OCCBody*>(lump->get_body());
01904     TopoDS_Shape *b_shape = NULL;
01905     if(body)
01906       body->get_TopoDS_Shape(b_shape);
01907     if (!body || b_shape == NULL)
01908     { 
01909       if(body)
01910         BodyList->remove(body);
01911       body = new OCCBody(NULL, NULL, NULL, lump);
01912       BodyList->append(body);
01913       lump->add_body(body);
01914     }
01915   }
01916 
01917   TopoDS_Compound *shape = NULL;
01918   if(body)
01919     shape = body->get_TopoDS_Shape();
01920 
01921   if(build_body && OCCMap->IsBound(aShape) && shape && !shape->IsNull())
01922   {
01923     PRINT_ERROR("Single lump body shouldn't have Compound shape.\n");
01924     return (Lump*) NULL;
01925   }
01926 
01927   TopExp_Explorer Ex;
01928   for (Ex.Init(aShape, TopAbs_SHELL); Ex.More(); Ex.Next())
01929   {
01930     TopoDS_Shape sh = Ex.Current();
01931     OCCShell* shell = populate_topology_bridge(TopoDS::Shell(sh));
01932     shell->set_lump(lump);
01933     shell->set_body(body);
01934     TopoDS_Shape parent = aShape;
01935     int current_id;
01936     add_shape_to_map(sh, parent, current_id);
01937     if(!OCCMap->IsBound(sh) ||
01938      OccToCGM->find(OCCMap->Find(sh)) == OccToCGM->end())
01939        OccToCGM->insert(valType(current_id, (TopologyBridge*)shell));
01940   } 
01941 
01942   if(build_body && (!OCCMap->IsBound(aShape)||
01943       OccToCGM->find(OCCMap->Find(aShape)) == OccToCGM->end()))
01944   {
01945     if (!OCCMap->IsBound(aShape))
01946       OCCMap->Bind(aShape, current_lump_number);
01947     OccToCGM->insert(valType(current_lump_number,
01948                        (TopologyBridge*)lump));
01949   }
01950   return lump;
01951 }
01952 
01953 void OCCQueryEngine::add_shape_to_map(TopoDS_Shape& sh,
01954                                       TopoDS_Shape& aShape, /*In, parent */
01955                                       int &current_id /*Out*/)
01956 {
01957   //add the shape into map
01958   if(sh.IsNull())
01959     return;
01960 
01961   if(!OCCMap->IsBound(sh) ||
01962      OccToCGM->find(OCCMap->Find(sh)) == OccToCGM->end())
01963   {
01964      DLIList<TopoDS_Shape*> list;
01965      //find the sh shape without aShape's location.
01966      TopLoc_Location L = aShape.Location();
01967      TopoDS_Iterator it(aShape, Standard_True, Standard_False);
01968      TopoDS_Shape bare_shape;
01969      for(; it.More(); it.Next())
01970      {
01971        TopoDS_Shape test_shape = it.Value();
01972        test_shape.Move(L);
01973        if(sh.IsEqual(test_shape))
01974        {
01975          bare_shape = it.Value();
01976          break;
01977        }
01978      }
01979      if(!OCCMap->IsBound(sh))
01980      {
01981        CubitBoolean shape_found = false;
01982        if(OCCMap->IsBound(bare_shape))
01983        {
01984          current_id = OCCMap->Find(bare_shape);
01985          //There are two possiblities when coming here:
01986          //1. After OCCAttribute binds the bare_shape but not binds the topo.
01987          //2. The bare_shape is bound because it binds to a different topo. 
01988          if( OccToCGM->find(current_id) == OccToCGM->end() )        
01989          {
01990            OCCMap->UnBind(bare_shape);
01991            std::map<int, TDF_Label>::iterator it = 
01992               Shape_Label_Map->find(current_id);
01993            if(it != Shape_Label_Map->end())
01994            {
01995              TDF_Label aLabel = (*it).second;
01996              Handle_TDataXtd_Shape attr_shape = TDataXtd_Shape::Set(aLabel, sh);
01997            }
01998            shape_found = true;
01999          }
02000        }
02001        if(!shape_found)
02002        {
02003          iTotalTBCreated++;
02004          current_id = iTotalTBCreated;
02005        }
02006        OCCMap->Bind(sh, current_id);
02007     }
02008     else
02009       current_id = OCCMap->Find(sh);
02010   }
02011   else
02012     current_id = OCCMap->Find(sh);
02013 }
02014 
02015 OCCShell* OCCQueryEngine::populate_topology_bridge(const TopoDS_Shell& aShape,
02016                            CubitBoolean standalone)
02017 {
02018   if(aShape.IsNull())
02019     return (OCCShell*)NULL;
02020   OCCShell *shell ;
02021   if (!OCCMap->IsBound(aShape) ||
02022       OccToCGM->find(OCCMap->Find(aShape)) == OccToCGM->end())
02023   {
02024     if(standalone)
02025     {
02026       //check if just has one Face,if so, don't make new shell.
02027       TopExp_Explorer Ex;
02028       int num_faces = 0;
02029       TopoDS_Face topo_face;
02030       for (Ex.Init(aShape, TopAbs_FACE); Ex.More(); Ex.Next())
02031       {
02032         topo_face = TopoDS::Face(Ex.Current());
02033         num_faces++;
02034       }
02035       if(num_faces == 1)
02036       {
02037         Surface* face = populate_topology_bridge(topo_face, standalone);
02038         return CAST_TO(face, OCCSurface)->my_shell();
02039       }
02040     }
02041     TopoDS_Shell *poshell = new TopoDS_Shell;
02042     *poshell = aShape;
02043     shell = new OCCShell(poshell);
02044     shell->set_body(NULL);
02045     shell->set_lump(NULL); 
02046     if(standalone)
02047     {
02048       OCCLump* lump = new OCCLump(NULL, NULL, shell);
02049       OCCBody* body = new OCCBody(NULL, NULL, shell);
02050       BodyList->append(body);
02051       shell->set_body(body);
02052       shell->set_lump(lump);
02053       int k;
02054       if(!OCCMap->IsBound(aShape))
02055       {
02056         iTotalTBCreated++;
02057         k = iTotalTBCreated;
02058         OCCMap->Bind(*poshell, k);
02059       }
02060       else
02061         k = OCCMap->Find(aShape); 
02062       OccToCGM->insert(valType(k, (TopologyBridge*)shell));
02063     }
02064   }
02065   else
02066   {
02067     int k = OCCMap->Find(aShape);
02068     shell = (OCCShell*)(OccToCGM->find(k))->second;
02069     shell->set_TopoDS_Shell(aShape);
02070   }
02071 
02072   DLIList<OCCSurface*> memberSurfaces;
02073   TopExp_Explorer Ex;
02074   for (Ex.Init(aShape, TopAbs_FACE); Ex.More(); Ex.Next())
02075   {
02076     TopoDS_Shape sh = Ex.Current();
02077     TopoDS_Face topo_face = TopoDS::Face(sh);
02078     Surface* face =
02079       populate_topology_bridge(topo_face, CUBIT_FALSE);
02080     
02081     TopoDS_Shape parent = aShape; 
02082     int current_id;
02083     add_shape_to_map(sh, parent, current_id);
02084     if(!OCCMap->IsBound(sh) ||
02085      OccToCGM->find(OCCMap->Find(sh)) == OccToCGM->end())
02086        OccToCGM->insert(valType(current_id, (TopologyBridge*)face));
02087 
02088     if(!face)
02089       continue;
02090     OCCSurface *occ_surface = CAST_TO(face, OCCSurface);
02091     //check if surface was a sheet surface, delete it if so
02092     if(occ_surface->my_shell() != NULL && occ_surface->my_shell() != shell)
02093     {
02094        //if Sheet_body, delete this sheet body
02095        OCCBody* occ_body = occ_surface->my_body();
02096        if(occ_body != NULL)
02097        {
02098           delete_solid_model_entities(occ_body);
02099           face =
02100             populate_topology_bridge(topo_face, CUBIT_FALSE);
02101    
02102           if(!face)
02103             continue;
02104           occ_surface = CAST_TO(face, OCCSurface);
02105           shell->set_sheet_surface(occ_surface);
02106        }
02107     }
02108 
02109     memberSurfaces.append(occ_surface);
02110     occ_surface->set_shell(shell);
02111   }
02112 
02113   shell->setMemberSurfaces(memberSurfaces);
02114   return shell;
02115 }
02116 
02117 Surface* OCCQueryEngine::populate_topology_bridge(const TopoDS_Face& aShape,
02118                                                   CubitBoolean build_body)
02119 {
02120   if(aShape.IsNull())
02121     return (Surface*)NULL;
02122   OCCSurface *surface = NULL;
02123   GProp_GProps myProps;
02124   BRepGProp::SurfaceProperties(aShape, myProps);
02125   double area = myProps.Mass();
02126   double tol = get_sme_resabs_tolerance();
02127   if(area < tol * tol && area > 0.)
02128     PRINT_WARNING("Generated a sliver surface. \n");
02129   
02130   else if (area < 0.0)
02131     PRINT_WARNING("Generated a negative area surface. \n");
02132 
02133   if (!OCCMap->IsBound(aShape) ||
02134       OccToCGM->find(OCCMap->Find(aShape)) == OccToCGM->end())
02135   {
02136     TopoDS_Face *poface = new TopoDS_Face;
02137     *poface = aShape;
02138     surface = new OCCSurface(poface);
02139     SurfaceList->append(surface);
02140     surface->set_body(NULL);
02141     surface->set_lump(NULL);
02142     surface->set_shell(NULL);
02143     if(build_body)
02144     {
02145       OCCShell* shell = new OCCShell(NULL, surface);
02146       OCCLump* lump = new OCCLump(NULL, surface);
02147       OCCBody* body = new OCCBody(NULL, surface);
02148       surface->set_body(body);
02149       surface->set_lump(lump);
02150       surface->set_shell(shell);
02151       shell->set_body(body);
02152       shell->set_lump(lump);
02153       BodyList->append(body);
02154       int k;
02155       if(!OCCMap->IsBound(aShape))
02156       {
02157         iTotalTBCreated++;
02158         k = iTotalTBCreated;
02159         OCCMap->Bind(*poface, iTotalTBCreated);
02160       }
02161       else
02162         k = OCCMap->Find(aShape);
02163       OccToCGM->insert(valType(k, (TopologyBridge*)surface));
02164     }
02165   } 
02166 
02167   else 
02168   {
02169     int k = OCCMap->Find(aShape);
02170     surface = (OCCSurface*)(OccToCGM->find(k))->second;
02171     TopoDS_Face aFace(aShape);
02172     surface->set_TopoDS_Face(aFace);
02173   }
02174 
02175   TopExp_Explorer Ex;
02176   for (Ex.Init(aShape.Oriented(TopAbs_FORWARD), TopAbs_WIRE); Ex.More();
02177       Ex.Next())
02178   {
02179     TopoDS_Shape sh = Ex.Current();
02180 
02181     OCCLoop* loop = populate_topology_bridge(TopoDS::Wire(sh));
02182 /*
02183     if( aShape.Orientation() == TopAbs_REVERSED )
02184     {
02185       DLIList<OCCCoEdge*> coedges_new = loop->coedges();
02186       coedges_new.reverse();
02187       //Reverse all coedges' senses.
02188       for (int i = 0; i < coedges_new.size(); i ++)
02189       {
02190         OCCCoEdge* coedge = coedges_new.get_and_step();
02191         CubitSense sense = (coedge->sense() == CUBIT_FORWARD ? CUBIT_REVERSED : CUBIT_FORWARD);
02192         coedge->set_sense(sense);
02193       }
02194       loop->coedges(coedges_new);
02195     } 
02196 */
02197     TopoDS_Shape parent = aShape;
02198     int current_id;
02199     add_shape_to_map(sh, parent, current_id);
02200     if(!OCCMap->IsBound(sh) ||
02201      OccToCGM->find(OCCMap->Find(sh)) == OccToCGM->end())
02202        OccToCGM->insert(valType(current_id, (TopologyBridge*)loop));
02203   } 
02204 
02205   return surface;
02206 }
02207 
02208 OCCLoop* OCCQueryEngine::populate_topology_bridge(const TopoDS_Wire& aShape,
02209                           CubitBoolean standalone)
02210 {
02211   if(aShape.IsNull())
02212     return (OCCLoop*)NULL;
02213 
02214   BRepTools_WireExplorer Ex;
02215 
02216   OCCLoop *loop ;
02217   if (!OCCMap->IsBound(aShape) ||
02218       OccToCGM->find(OCCMap->Find(aShape)) == OccToCGM->end())
02219   {
02220     TopoDS_Wire *powire = new TopoDS_Wire;
02221     *powire = aShape;
02222     loop = new OCCLoop(powire);
02223     if(standalone)
02224     {
02225       int k;
02226       if(!OCCMap->IsBound(aShape))
02227       {
02228         iTotalTBCreated++;
02229         k = iTotalTBCreated;
02230         OCCMap->Bind(aShape, iTotalTBCreated);
02231       }
02232       else
02233         k = OCCMap->Find(aShape);
02234       OccToCGM->insert(valType(k, (TopologyBridge*)loop));
02235       WireList->append(loop);
02236     }
02237   }
02238   else
02239   {
02240     int k = OCCMap->Find(aShape);
02241     loop = (OCCLoop*)(OccToCGM->find(k))->second;
02242     loop->set_TopoDS_Wire(aShape);
02243   }
02244 
02245   CubitVector v;
02246 
02247   DLIList <OCCCoEdge*> coedges_old, coedges_new;
02248   coedges_old = loop->coedges();
02249 
02250   for (Ex.Init(aShape); Ex.More(); Ex.Next())
02251   {
02252     const TopoDS_Edge& anEdgeForPop = Ex.Current();
02253     TopoDS_Shape crv = anEdgeForPop;
02254     Curve* curve = populate_topology_bridge(anEdgeForPop);
02255     if(!curve)
02256       continue;
02257     TopoDS_Shape parent = aShape;
02258     int current_id;
02259     add_shape_to_map(crv, parent, current_id);
02260     if(!OCCMap->IsBound(crv) ||
02261      OccToCGM->find(OCCMap->Find(crv)) == OccToCGM->end())
02262        OccToCGM->insert(valType(current_id, (TopologyBridge*)curve));
02263 
02264     OCCCurve *occ_curve = CAST_TO(curve, OCCCurve);
02265     DLIList<OCCLoop*> loops = occ_curve->loops();
02266     CubitBoolean exist = CUBIT_FALSE;
02267     OCCCoEdge * coedge = NULL;
02268     int size = coedges_old.size();
02269     CubitSense sense = (crv.Orientation() == TopAbs_FORWARD ?
02270         CUBIT_FORWARD : CUBIT_REVERSED);
02271 
02272     //for the cylinder side face, there are 4 coedges, 2 of them are seam
02273     //edges and should have opposite sense.
02274     for(int i = 0; i < coedges_new.size(); i++)
02275     {
02276       coedge =  coedges_new.get_and_step();
02277       Curve* test_c = coedge->curve();
02278       if(test_c == curve)
02279       {       
02280         if(sense == coedge->sense())
02281           sense = (sense == CUBIT_FORWARD ? CUBIT_REVERSED : CUBIT_FORWARD);
02282         
02283         break;    
02284       }
02285     }
02286 
02287     for(int i = 0; i < size; i++)
02288     {
02289       coedge = coedges_old.get_and_step();
02290       if(coedge->curve() == curve && coedge->sense() ==  sense)
02291       {
02292         coedge->set_mark(1);
02293         exist = CUBIT_TRUE;
02294         coedge->set_sense(sense);
02295         coedges_new.append(coedge);
02296         break;
02297       }
02298     }   
02299     
02300     if(!exist )
02301     {
02302       //search through the curve loops
02303       for(int i = 0; i < loops.size() ; i++)
02304       {
02305         OCCLoop* occ_loop = loops.get_and_step();
02306         TopoDS_Wire* wire = occ_loop->get_TopoDS_Wire();
02307         if (size > 0 && (wire->IsNull() || !OCCMap->IsBound(*wire)))
02308         { 
02309           DLIList<OCCCoEdge*> coedge_list = occ_loop->coedges();
02310           for(int j = 0; j < coedge_list.size(); j++)
02311           {
02312             OCCCoEdge * test_coedge = coedge_list.get_and_step();
02313             occ_loop->remove_coedge(test_coedge);
02314             occ_curve->remove_loop(occ_loop);
02315             delete test_coedge;
02316           }
02317           if(!wire->IsNull())
02318             wire->Nullify();
02319           WireList->remove(occ_loop);
02320         }
02321       }
02322 
02323       if(occ_curve->loops().size() == 2)
02324       {
02325         // If there are some assumptions made about manifold geometry . . .
02326         //there must be a loop which doesn't have this curve anymore
02327         //this is been found in subtract cases while one solid becomes
02328         //2 solid, and one face becomes two faces. One face uses/updates
02329         //the old face while the other face generates face and wire from
02330         //new. However, in order to uses the curves, the old curve is kept
02331         //as possible, so curve's loops get kept, but since it's going to 
02332         //associate with new loop, the old loop should be removed from the 
02333         //loop list.
02334         DLIList<OCCLoop*> old_loops = occ_curve->loops();
02335         for (int i = 0; i < 2; i++)
02336         {
02337           int found = 0;
02338           OCCLoop* old_loop = old_loops.get_and_step();
02339           TopoDS_Wire* thewire = old_loop->get_TopoDS_Wire();
02340           if (thewire < (void*) 0x1000 || thewire->IsNull())
02341           {
02342             found = 1;
02343             break;
02344           }
02345           DLIList<OCCCoEdge*> test_coedges = old_loop->coedges();
02346           for(int j = 0; j < test_coedges.size() ; j++)
02347           {
02348             if(test_coedges.get()->curve() != curve)
02349               test_coedges.step();
02350             else
02351             {
02352               found = 1;
02353               break;
02354             }
02355           }
02356           if(!found)
02357             occ_curve->remove_loop(old_loop); 
02358         }  
02359       }
02360       //for unite case, it's possible that the a curve has 3 coedges because
02361       //opencascade do not perform unite on surfaces.
02362       coedge = new OCCCoEdge( curve, loop, sense);
02363       coedges_new.append(coedge);
02364       occ_curve->add_loop(loop);
02365     }
02366   }
02367 
02368   //Double check edge sense to make sure it consists with loop direction
02369   //coedges size = 2 case is checked in the face level so the face normal will
02370   //be considered.
02371   if(coedges_new.size() > 2)
02372   {
02373     OCCCoEdge* coedge = coedges_new.get_and_step();
02374     double    d1, d1_, d2, d2_;
02375     OCCCoEdge* next_coedge = coedges_new.get();
02376     //because of tolerance issue, now check current loop end vertices distance
02377     //compared with reversed loop's end vertices distance, which ever shorter
02378     //will be the direction.
02379     //current loop's parameter not using " _ ", reversed loop's parameter
02380     //uses " _ ".
02381     if (coedge->sense() == CUBIT_FORWARD)
02382     { 
02383       d1 = coedge->curve()->end_param();
02384       d1_ = coedge->curve()->start_param();
02385     }
02386     else
02387     {
02388       d1 = coedge->curve()->start_param();
02389       d1_ = coedge->curve()->end_param();
02390     }
02391     if( next_coedge->sense() == CUBIT_FORWARD)
02392     {
02393       d2_ = next_coedge->curve()->end_param();
02394       d2 = next_coedge->curve()->start_param();
02395     }
02396     else
02397     {
02398       d2 = next_coedge->curve()->end_param();
02399       d2_ = next_coedge->curve()->start_param();
02400     } 
02401     CubitVector v1, v1_, v2, v2_;
02402     coedge->curve()->position_from_u(d1, v1);
02403     coedge->curve()->position_from_u(d1_, v1_);
02404     next_coedge->curve()->position_from_u(d2, v2);
02405     next_coedge->curve()->position_from_u(d2_, v2_);
02406     if(v1.distance_between(v2) > v1_.distance_between(v2_))
02407     {
02408       //Reverse all coedges' senses.
02409       for (int i = 0; i < coedges_new.size(); i ++)
02410       {
02411         coedge = coedges_new.get_and_step();
02412         CubitSense sense = (coedge->sense() == CUBIT_FORWARD ? CUBIT_REVERSED : CUBIT_FORWARD);
02413         coedge->set_sense(sense);
02414       }
02415     }
02416   }
02417 
02418 /*
02419   if(aShape.Orientation() == TopAbs_REVERSED)
02420     coedges_new.reverse();
02421   //Reverse all coedges' senses.
02422   for (int i = 0; i < coedges_new.size(); i ++)
02423   {
02424     OCCCoEdge* coedge = coedges_new.get_and_step();
02425     CubitSense sense = (coedge->sense() == CUBIT_FORWARD ? CUBIT_REVERSED : CUBIT_FORWARD);
02426     coedge->set_sense(sense);
02427   }
02428 */
02429   loop->coedges(coedges_new);
02430 
02431   //remove unused coedges
02432   for(int i = 0; i < coedges_old.size(); i++)
02433   {
02434     OCCCoEdge *coedge = coedges_old.get_and_step();
02435     if(coedge->get_mark() == 0)
02436       delete coedge;
02437     else
02438       coedge->set_mark(0);
02439   }
02440   return loop;
02441 }
02442 
02443 Curve* OCCQueryEngine::populate_topology_bridge(const TopoDS_Edge& aShape,
02444                                                 CubitBoolean stand_along )
02445 {
02446   if(aShape.IsNull())
02447     return (Curve*)NULL;
02448   Curve *curve;
02449   GProp_GProps myProps;
02450   BRepGProp::LinearProperties(aShape, myProps);
02451   double length =  myProps.Mass();
02452   TopExp_Explorer Ex;
02453   if(length < get_sme_resabs_tolerance())
02454   {
02455     //check if the two vertices are acctually the same point.
02456     CubitVector v[2];
02457     int i = 0;
02458     for (Ex.Init(aShape, TopAbs_VERTEX); Ex.More(); Ex.Next())
02459     {
02460       TopoDS_Vertex vt = TopoDS::Vertex(Ex.Current());
02461       gp_Pnt pt = BRep_Tool::Pnt(vt);
02462       v[i] = CubitVector(pt.X(), pt.Y(), pt.Z());
02463       i++;
02464     }  
02465       
02466     if(v[0] == v[1])
02467       return (Curve*) NULL;
02468     else  
02469       PRINT_WARNING("Generated a sliver curve. \n");
02470   }
02471 
02472   if (!OCCMap->IsBound(aShape) ||
02473       OccToCGM->find(OCCMap->Find(aShape)) == OccToCGM->end())
02474   {
02475     TopoDS_Edge *poedge = new TopoDS_Edge;
02476     *poedge = aShape;
02477     curve = new OCCCurve(poedge);
02478     CurveList->append((OCCCurve*)curve);
02479     if(stand_along)
02480     {
02481       int k;
02482       if(!OCCMap->IsBound(aShape)) 
02483       {
02484         iTotalTBCreated++;
02485         k = iTotalTBCreated;
02486         OCCMap->Bind(*poedge, iTotalTBCreated);
02487       }
02488       else 
02489         k = OCCMap->Find(aShape);
02490       OccToCGM->insert(valType(k, (TopologyBridge*)curve));
02491     }
02492   }
02493   else 
02494   {
02495     int i = OCCMap->Find(aShape);
02496     curve = (Curve*)(OccToCGM->find(i))->second;
02497     CAST_TO(curve, OCCCurve)->set_TopoDS_Edge(aShape);
02498   }
02499 
02500   for (Ex.Init(aShape, TopAbs_VERTEX); Ex.More(); Ex.Next())
02501   {
02502     TopoDS_Shape sh = Ex.Current();
02503 
02504    /* bool alreadyWrapped=false;
02505     if(OCCMap->IsBound(sh))
02506     {
02507       alreadyWrapped=true;
02508     }*/
02509 
02510     TBPoint* point = populate_topology_bridge(TopoDS::Vertex(Ex.Current()));
02511     CAST_TO(point, OCCPoint)->add_curve(CAST_TO(curve, OCCCurve));
02512     TopoDS_Shape parent = aShape;
02513     int current_id;
02514     add_shape_to_map(sh, parent, current_id);
02515     if(!OCCMap->IsBound(sh) ||
02516      OccToCGM->find(OCCMap->Find(sh)) == OccToCGM->end())
02517        OccToCGM->insert(valType(current_id, (TopologyBridge*)point));
02518      
02519   
02520    /* if(alreadyWrapped)
02521        PRINT_INFO("Vertex Already Wrapped:     "); 
02522     else
02523        PRINT_INFO("Vertex Wrapped:     ");  
02524     PRINT_INFO("     Shape ID = %d",  OCCMap->Find(sh) ); 
02525     PRINT_INFO("     TBPoint Address: %p", point );  
02526     PRINT_INFO("     Shape Orientation: %s\n", sh.Orientation()==TopAbs_FORWARD ? "Forward" : "Reversed" ); 
02527 */
02528 
02529   }
02530 
02531   return curve;
02532 }
02533 
02534 TBPoint* OCCQueryEngine::populate_topology_bridge(const TopoDS_Vertex& aShape,
02535                                                 CubitBoolean stand_along)
02536 {
02537   if(aShape.IsNull())
02538     return (TBPoint*)NULL;
02539   OCCPoint *point;
02540   if (iTotalTBCreated == 0 || !OCCMap->IsBound(aShape) ||
02541       OccToCGM->find(OCCMap->Find(aShape)) == OccToCGM->end()) 
02542   {
02543     TopoDS_Vertex *povertex = new TopoDS_Vertex;
02544     *povertex = aShape;
02545     point = new OCCPoint(povertex);
02546     if(stand_along)
02547     { 
02548       int k;
02549       if(!OCCMap->IsBound(aShape)) 
02550       {
02551         iTotalTBCreated++;
02552         k = iTotalTBCreated;
02553         OCCMap->Bind(*povertex, iTotalTBCreated);
02554       }
02555       else 
02556         k = OCCMap->Find(aShape);
02557       OccToCGM->insert(valType(k, (TopologyBridge*)point));
02558     }
02559 
02560   } 
02561   else 
02562   {
02563     int i = OCCMap->Find(aShape);
02564     point = (OCCPoint*)(OccToCGM->find(i))->second;
02565     point->set_TopoDS_Vertex(aShape);
02566   }
02567   return point;
02568 }
02569 
02570 TopologyBridge* OCCQueryEngine::occ_to_cgm(const TopoDS_Shape& shape)
02571 {
02572   if(!OCCMap->IsBound(shape))
02573     return (TopologyBridge*) NULL;
02574 
02575   int k = OCCMap->Find(shape);
02576   return (OccToCGM->find(k))->second;
02577 }   
02578 
02579 //-----------------------------------------------------------------------
02580 // Purpose       : Deletes all solid model entities associated with the
02581 //                 Bodies in the input list.
02582 //
02583 // Special Notes :
02584 //
02585 // Creator       : Jane Hu
02586 //
02587 // Creation Date : 7/23/11
02588 //-------------------------------------------------------------------------
02589 void OCCQueryEngine::delete_solid_model_entities(DLIList<BodySM*>&bodyList)const
02590 {
02591   delete_bodies(bodyList, true);
02592 }
02593  
02594 //-------------------------------------------------------------------------
02595 // Purpose       : Deletes all solid model entities associated with the
02596 //                 Bodies in the input list depending on remove_lower_entities
02597 //                 flag.
02598 //
02599 // Special Notes :
02600 //
02601 // Creator       : Steve Owen
02602 //
02603 // Creation Date : 4/23/01
02604 //-------------------------------------------------------------------------
02605 void OCCQueryEngine::delete_bodies(DLIList<BodySM*>&bodyList,
02606                                    bool remove_lower_entities ) const
02607 {
02608   BodySM* BodyPtr = NULL;
02609   for (int i = 0; i < bodyList.size(); i++ )
02610     {
02611       BodyPtr = bodyList.get_and_step();
02612       this->delete_body(BodyPtr, remove_lower_entities);
02613     }
02614 
02615   return;
02616 }
02617 
02618 CubitStatus OCCQueryEngine::delete_solid_model_entities(
02619     GeometryEntity* ref_entity_ptr,
02620     bool remove_lower_entities) const
02621 {
02622      //Lump
02623    Lump* lump = CAST_TO(ref_entity_ptr, Lump);
02624    if(lump != NULL)
02625    {
02626      BodySM* body = CAST_TO(lump, OCCLump)->get_body();
02627      DLIList<Lump*> lumps = CAST_TO(body, OCCBody)->lumps();
02628  
02629      if (remove_lower_entities)
02630        return delete_solid_model_entities(body);
02631 
02632      DLIList<TopologyBridge*> children;
02633      for(int i = 0; i < lumps.size(); i++)
02634      {
02635        lump = lumps.get_and_step();
02636        CAST_TO(lump, OCCLump)->get_children_virt(children);
02637      }
02638 
02639      CubitStatus stat = this->unhook_BodySM_from_OCC(body); 
02640      if(stat)
02641      {
02642        while (children.size())
02643           delete children.pop();
02644        while(lumps.size())
02645           delete lumps.pop();
02646        delete body;
02647      }
02648      return stat;
02649    }
02650 
02651      // Surface
02652    Surface* ref_face_ptr = CAST_TO(ref_entity_ptr, Surface);
02653    if (ref_face_ptr != NULL)
02654    {
02655      if (remove_lower_entities)
02656        return ( this->delete_solid_model_entities(ref_face_ptr) );
02657      CubitStatus stat = this->unhook_Surface_from_OCC(ref_face_ptr);
02658      if(stat)
02659        delete ref_face_ptr;
02660      return stat;
02661    }
02662 
02663      // Curve
02664    Curve* ref_edge_ptr = CAST_TO(ref_entity_ptr, Curve);
02665    if (ref_edge_ptr != NULL)
02666    {
02667       if (remove_lower_entities)
02668         return ( this->delete_solid_model_entities(ref_edge_ptr));
02669       CubitStatus stat = this->unhook_Curve_from_OCC(ref_edge_ptr);
02670       if(stat)
02671         delete ref_edge_ptr;
02672       return stat;
02673    }
02674 
02675      // Point
02676    TBPoint* ref_vertex_ptr = CAST_TO(ref_entity_ptr, TBPoint);
02677    if (ref_vertex_ptr != NULL)
02678    {
02679       return ( this->delete_solid_model_entities(ref_vertex_ptr) );
02680    }
02681 
02682      // Oops!
02683    PRINT_ERROR("In OCCQueryEngine::delete_solid_model_entities\n"
02684                "       Can only delete solid model entities underlying \n"
02685                "RefFaces, RefEdges and RefVertices.\n");
02686    return CUBIT_FAILURE;
02687 
02688 }
02689 //-------------------------------------------------------------------------
02690 // Purpose       : Delete a OCCBody and child entities.
02691 //
02692 // Special Notes :
02693 //
02694 // Creator       : Jane Hu
02695 //
02696 // Creation Date : 10/29/07
02697 //-------------------------------------------------------------------------
02698 CubitStatus
02699 OCCQueryEngine::delete_solid_model_entities( BodySM* bodysm) const
02700 {
02701   return delete_body(bodysm, true);
02702 }
02703 //-------------------------------------------------------------------------
02704 // Purpose       : Delete a OCCBody and child entities depending on
02705 //                 remove_lower_entities flag.
02706 //
02707 // Special Notes :
02708 //
02709 // Creator       : Jane Hu
02710 //
02711 // Creation Date : 10/29/07
02712 //-------------------------------------------------------------------------
02713 CubitStatus
02714 OCCQueryEngine::delete_body( BodySM* bodysm,
02715                              bool remove_lower_entities) const
02716 {
02717   OCCBody* occ_body = static_cast<OCCBody*>(bodysm);
02718   if (!occ_body)
02719     return CUBIT_FAILURE;
02720 
02721   DLIList<Lump*> lumps;
02722   DLIList<ShellSM*> shell_list;
02723   DLIList<OCCSurface*> surfaces = occ_body->my_sheet_surfaces();
02724   for(int i = 0;  i <surfaces.size(); i++)
02725   { 
02726     OCCSurface* occ_surface = surfaces.get_and_step();
02727     occ_surface->set_body((OCCBody*)NULL);
02728     if(remove_lower_entities)
02729     {
02730       delete occ_surface->my_lump();
02731       OCCShell* shell = occ_surface->my_shell();
02732       delete_solid_model_entities(occ_surface);
02733       delete shell;
02734     }
02735   }
02736 
02737   DLIList<OCCShell*> shells = occ_body->shells();
02738   for(int i = 0;  i <shells.size(); i++)
02739   {
02740     OCCShell* occ_shell = shells.get_and_step();
02741     occ_shell->set_body((OCCBody*)NULL);
02742     if(remove_lower_entities)
02743     {
02744       delete occ_shell->my_lump();
02745       DLIList<TopologyBridge*> tb_surfaces;
02746       occ_shell->get_children_virt(tb_surfaces);
02747       unhook_ShellSM_from_OCC(occ_shell);
02748       for(int k = 0; k < tb_surfaces.size(); k++)
02749         delete_solid_model_entities(CAST_TO(tb_surfaces.get_and_step(), Surface));
02750       delete occ_shell;
02751     }
02752   }
02753 
02754   DLIList<TopologyBridge*> children;
02755   lumps = occ_body->lumps();
02756   int size = lumps.size();
02757 
02758   for(int i =0; i < size; i++)
02759   {
02760     Lump* lump = lumps.get_and_step();
02761     OCCLump* occ_lump = CAST_TO(lump, OCCLump);
02762     if (!occ_lump)
02763        continue;
02764     occ_lump->remove_body();
02765     if(remove_lower_entities)
02766     {
02767       children.clean_out();
02768       occ_lump->get_children_virt(children);
02769       for(int j = 0; j < children.size(); j++)
02770       {
02771         ShellSM* shell = CAST_TO(children.get_and_step(), ShellSM);
02772       
02773         if (shell)
02774           shell_list.append(shell);
02775         DLIList<TopologyBridge*> tb_surfaces;
02776         shell->get_children_virt(tb_surfaces);
02777         for(int k = 0; k < tb_surfaces.size(); k++)
02778           delete_solid_model_entities(CAST_TO(tb_surfaces.get_and_step(), Surface));
02779       }
02780     }
02781   }
02782   CubitStatus stat = CUBIT_SUCCESS;
02783   stat = unhook_BodySM_from_OCC(bodysm, remove_lower_entities);
02784 
02785   if(remove_lower_entities)
02786   {
02787     for(int j = 0; j < shell_list.size(); j++)
02788        delete shell_list.get_and_step();
02789 
02790     for(int i =0; i < lumps.size(); i++)
02791        delete lumps.get_and_step(); 
02792   }
02793 
02794   BodyList->remove(occ_body);
02795   delete bodysm;
02796   return stat;
02797 }
02798 
02799 CubitStatus
02800 OCCQueryEngine::unhook_BodySM_from_OCC( BodySM* bodysm ,
02801                                         bool remove_lower_entities)const
02802 {
02803   OCCBody* occ_body = dynamic_cast<OCCBody*>(bodysm);
02804   if (!occ_body)
02805     return CUBIT_FAILURE;
02806 
02807   TopoDS_Shape* shape = occ_body->get_TopoDS_Shape();
02808 
02809   if (shape && !shape->IsNull())
02810   {
02811     //remove the entry from label tree
02812     OCCAttribSet::remove_attribute(*shape) ;
02813 
02814     //remove the entry from the map
02815     int k;
02816     if(shape && !shape->IsNull() && OCCMap->IsBound(*shape))
02817     {
02818         k = OCCMap->Find(*shape);
02819         OCCMap->UnBind(*shape);
02820 
02821         if(!OccToCGM->erase(k))
02822           PRINT_ERROR("The OccBody and iCreatedTotal %i pair is not in the map!", k);
02823     }
02824   }
02825 
02826   DLIList<Lump*> lumps = occ_body->lumps();
02827   for(int i =0; i < lumps.size()&& remove_lower_entities; i++)
02828   {
02829      Lump* lump = lumps.get_and_step();
02830      //OCCLump* occ_lump = CAST_TO(lump, OCCLump);
02831      //if(occ_lump)
02832      //  occ_lump->remove_body();
02833 
02834      unhook_Lump_from_OCC(lump);
02835   }
02836 
02837   if (shape && !shape->IsNull())
02838     shape->Nullify();
02839   return CUBIT_SUCCESS;
02840 } 
02841   
02842 //-------------------------------------------------------------------------
02843 // Purpose       : unhook a OCClumps and child entities.
02844 //
02845 // Special Notes :
02846 //
02847 // Creator       : Jane Hu
02848 //
02849 // Creation Date : 11/29/07
02850 //-------------------------------------------------------------------------
02851 CubitStatus
02852 OCCQueryEngine::unhook_Lump_from_OCC( Lump* lump ) const
02853 {
02854   if (lump == NULL)
02855     return CUBIT_FAILURE;
02856 
02857   OCCLump* occ_lump = dynamic_cast<OCCLump*>(lump);
02858   if (!occ_lump)
02859     return CUBIT_FAILURE;
02860 
02861   TopoDS_Solid* solid = occ_lump->get_TopoDS_Solid();
02862 
02863   if(!solid)
02864     return CUBIT_FAILURE;
02865 
02866   //remove the entry from label tree
02867   OCCAttribSet::remove_attribute(*solid) ;
02868 
02869   //remove the entry from the map
02870   int k;
02871   if(OCCMap->IsBound(*solid))
02872     {
02873       k = OCCMap->Find(*solid);
02874 
02875       OCCMap->UnBind(*solid);
02876 
02877       if(!OccToCGM->erase(k))
02878     PRINT_ERROR("The OccLump and iCreatedTotal pair is not in the map!");
02879     }
02880   
02881   DLIList<TopologyBridge*> children;
02882   occ_lump->get_children_virt(children);
02883   for(int i = 0; i < children.size(); i++)
02884   {
02885      ShellSM* shell = CAST_TO(children.get_and_step(), ShellSM); 
02886      unhook_ShellSM_from_OCC(shell);
02887   }
02888   if (occ_lump->get_body() != NULL)
02889     BodyList->remove(CAST_TO(occ_lump->get_body(), OCCBody));
02890 
02891   if(!solid->IsNull())
02892      solid->Nullify();
02893   return CUBIT_SUCCESS;
02894 } 
02895 
02896 //-------------------------------------------------------------------------
02897 // Purpose       : unhook a ShellSM from its underlining OCC entity.
02898 //
02899 // Special Notes :
02900 //
02901 // Creator       : Jane Hu
02902 //
02903 // Creation Date : 12/12/07
02904 //-------------------------------------------------------------------------
02905 CubitStatus
02906 OCCQueryEngine::unhook_ShellSM_from_OCC( ShellSM* shell) const
02907 {
02908   OCCShell* occ_shell = dynamic_cast<OCCShell*>(shell);
02909   if (!occ_shell)
02910     return CUBIT_FAILURE;
02911 
02912   TopoDS_Shell* Shell = occ_shell->get_TopoDS_Shell();
02913 
02914   if(!Shell)
02915     return CUBIT_FAILURE;
02916 
02917   //remove the entry from the map
02918   int k;
02919   if(OCCMap->IsBound(*Shell))
02920     {
02921       k = OCCMap->Find(*Shell);
02922 
02923       OCCMap->UnBind(*Shell);
02924 
02925       if(!OccToCGM->erase(k))
02926         PRINT_ERROR("The OccShell and iCreatedTotal pair is not in the map!");
02927     }
02928 
02929   if(!Shell->IsNull())
02930     Shell->Nullify();
02931   return CUBIT_SUCCESS;
02932 }
02933 
02934 //-------------------------------------------------------------------------
02935 // Purpose       : Delete a OCCSurface and child entities.
02936 //
02937 // Special Notes :
02938 //
02939 // Creator       : Jane Hu
02940 //
02941 // Creation Date : 10/29/07
02942 //-------------------------------------------------------------------------
02943 CubitStatus
02944 OCCQueryEngine::delete_solid_model_entities( Surface* surface)const
02945 {
02946   OCCSurface* fsurf = dynamic_cast<OCCSurface*>(surface);
02947   if (!fsurf)
02948     return CUBIT_FAILURE;
02949 
02950   OCCBody* sheet_body = fsurf->my_body();
02951   if(sheet_body != NULL)
02952     BodyList->remove(sheet_body);
02953 
02954   double d = fsurf->measure();
02955   if(d < 0.0)
02956     PRINT_WARNING("Negative area surface is being deleted. \n");
02957 
02958   DLIList<TopologyBridge*> children;
02959   fsurf->get_children_virt(children);
02960   for(int i = 0; i < children.size(); i++)
02961   {
02962      LoopSM* loop = CAST_TO(children.get_and_step(), LoopSM);
02963      delete_loop(loop);
02964   }
02965   CubitStatus stat = unhook_Surface_from_OCC(surface);
02966   if (stat)
02967     delete surface;
02968   return stat;
02969 }
02970 
02971 //-------------------------------------------------------------------------
02972 // Purpose       : unhook a Surface from its underlining OCC entity.
02973 //
02974 // Special Notes :
02975 //
02976 // Creator       : Jane Hu
02977 //
02978 // Creation Date : 12/12/07
02979 //-------------------------------------------------------------------------
02980 CubitStatus
02981 OCCQueryEngine::unhook_Surface_from_OCC( Surface* surface) const
02982 {
02983   OCCSurface* fsurf = dynamic_cast<OCCSurface*>(surface);
02984   if (!fsurf)
02985     return CUBIT_FAILURE;
02986 
02987   TopoDS_Face *face = fsurf->get_TopoDS_Face();
02988 
02989   if(!face)
02990     return CUBIT_FAILURE;
02991 
02992   //remove the entry from label tree
02993   OCCAttribSet::remove_attribute(*face) ;
02994 
02995   //remove the entry from the map
02996   int k;
02997   if(OCCMap->IsBound(*face))
02998     {
02999       k = OCCMap->Find(*face);
03000 
03001       OCCMap->UnBind(*face);
03002 
03003       if(!OccToCGM->erase(k))
03004         PRINT_WARNING("The OccSurface and iCreatedTotal pair is not in the map!");
03005     }
03006   SurfaceList->remove(fsurf);
03007   if(!face->IsNull())
03008     face->Nullify();
03009   return CUBIT_SUCCESS;
03010 }
03011 
03012 //-------------------------------------------------------------------------
03013 // Purpose       : Delete a OCCLoop and child entities.
03014 //
03015 // Special Notes :
03016 //
03017 // Creator       : Jane Hu
03018 //
03019 // Creation Date : 10/29/07
03020 //-------------------------------------------------------------------------
03021 CubitStatus
03022 OCCQueryEngine::delete_loop( LoopSM* loopsm)const
03023 {
03024   OCCLoop* occ_loop = dynamic_cast<OCCLoop*>(loopsm);
03025   if (!occ_loop)
03026     return CUBIT_FAILURE;
03027 
03028   DLIList<OCCCoEdge*> children;
03029   children = occ_loop->coedges();
03030   int size = children.size();
03031   DLIList<Curve*> curves;
03032   while(size > 0)
03033   {
03034      OCCCoEdge* coedge = children.pop();
03035      Curve* curve = coedge->curve();
03036      curves.append_unique(curve);
03037      size = children.size();
03038   }
03039    
03040   CubitStatus status = unhook_LoopSM_from_OCC(loopsm);
03041 
03042   for(int i = 0; i < curves.size(); i ++)
03043   {
03044     OCCCurve* occ_curve = CAST_TO(curves.get_and_step(), OCCCurve);
03045     unhook_coedges_of_a_curve(occ_curve, occ_loop);
03046     occ_curve->remove_loop(occ_loop);
03047     delete_solid_model_entities(occ_curve);
03048   }
03049 
03050   if (status)
03051   {
03052     WireList->remove(occ_loop);
03053     delete loopsm;
03054   }
03055   return status;
03056 }
03057 
03058 //-------------------------------------------------------------------------
03059 // Purpose       : unhook a LoopSM from its underlining OCC entity.
03060 //
03061 // Special Notes :
03062 //
03063 // Creator       : Jane Hu
03064 //
03065 // Creation Date : 12/12/07
03066 //-------------------------------------------------------------------------
03067 CubitStatus
03068 OCCQueryEngine::unhook_LoopSM_from_OCC( LoopSM* loopsm) const
03069 {
03070   OCCLoop* occ_loop = dynamic_cast<OCCLoop*>(loopsm);
03071   if (!occ_loop)
03072     return CUBIT_FAILURE;
03073 
03074   TopoDS_Wire* wire = occ_loop->get_TopoDS_Wire();
03075 
03076   if(!wire)
03077     return CUBIT_FAILURE;
03078 
03079   //remove the entry from the map
03080   int k;
03081   if(OCCMap->IsBound(*wire))
03082     {
03083       k = OCCMap->Find(*wire);
03084 
03085       OCCMap->UnBind(*wire);
03086 
03087       if(!OccToCGM->erase(k))
03088         PRINT_ERROR("The OccLoop and iCreatedTotal pair is not in the map!");
03089     }
03090 
03091   if(!wire->IsNull())
03092     wire->Nullify(); 
03093   return CUBIT_SUCCESS;
03094 }
03095 
03096 //-------------------------------------------------------------------------
03097 // Purpose      : unhook a list of OCCCoEdges from their underlining OCC entity.
03098 //
03099 // Special Notes :
03100 //
03101 // Creator       : Jane Hu
03102 //
03103 // Creation Date : 12/12/07
03104 //-------------------------------------------------------------------------
03105 CubitStatus
03106 OCCQueryEngine::unhook_CoEdges_from_OCC( DLIList<OCCCoEdge*>& coedges) const
03107 {
03108   int size = coedges.size();
03109   while(size > 0)
03110   {
03111      OCCCoEdge* coedge = coedges.pop();
03112 
03113      LoopSM* loopsm = coedge->loop();
03114      OCCLoop* loop = CAST_TO(loopsm, OCCLoop);
03115      assert(loop);
03116      loop->remove_coedge(coedge);
03117  
03118      delete coedge;
03119 
03120      size = coedges.size();
03121   }
03122   return CUBIT_SUCCESS;
03123 }
03124 
03125 //-------------------------------------------------------------------------
03126 // Purpose       : Delete a OCCCurve and child entities.
03127 //
03128 // Special Notes :
03129 //
03130 // Creator       : Jason Kraftcheck
03131 //
03132 // Creation Date : 09/29/03
03133 //-------------------------------------------------------------------------
03134 CubitStatus
03135 OCCQueryEngine::delete_solid_model_entities( Curve* curve)const
03136 {
03137   OCCCurve* fcurve = CAST_TO(curve, OCCCurve);
03138   if (!fcurve )
03139     return CUBIT_FAILURE;
03140 
03141   if(fcurve->loops().size() > 0 && fcurve->loops().get() != NULL)
03142     return CUBIT_FAILURE;
03143 
03144   DLIList<TopologyBridge*> children;
03145   fcurve->get_children_virt(children);
03146   for(int i = 0; i < children.size(); i++)
03147   {
03148      TBPoint* point = CAST_TO(children.get_and_step(), TBPoint);
03149      CAST_TO(point, OCCPoint)->remove_curve(fcurve);
03150      delete_solid_model_entities(point);
03151   }
03152   
03153   CubitStatus stat = unhook_Curve_from_OCC(curve);
03154   if (!stat)
03155     return CUBIT_FAILURE;
03156 
03157   CurveList->remove(fcurve);
03158   delete fcurve;
03159   return stat;
03160 }
03161 
03162 //-------------------------------------------------------------------------
03163 // Purpose       : unhook a Curve from its underlining OCC entity.
03164 //
03165 // Special Notes :
03166 //
03167 // Creator       : Jane Hu
03168 //
03169 // Creation Date : 12/12/07
03170 //-------------------------------------------------------------------------
03171 CubitStatus
03172 OCCQueryEngine::unhook_Curve_from_OCC( Curve* curve ) const
03173 {
03174   OCCCurve* fcurve = dynamic_cast<OCCCurve*>(curve);
03175   if (!fcurve )
03176     return CUBIT_FAILURE;
03177 
03178   DLIList<TopologyBridge*> children;
03179   fcurve->get_children_virt(children);
03180   for(int i = 0; i < children.size(); i++)
03181   {
03182      TBPoint* point = CAST_TO(children.get_and_step(), TBPoint);
03183      CAST_TO(point, OCCPoint)->remove_curve(fcurve);
03184   }
03185 
03186   unhook_coedges_of_a_curve(fcurve, NULL);
03187     
03188   fcurve->clean_loops();
03189   TopoDS_Edge* edge = fcurve->get_TopoDS_Edge();
03190   if (!edge)
03191     return CUBIT_FAILURE;
03192 
03193   //remove the entry from label tree
03194   OCCAttribSet::remove_attribute(*edge) ;
03195   
03196   //remove the entry from the map
03197   int k;
03198   if(edge && !edge->IsNull() && OCCMap->IsBound(*edge))
03199     {
03200       k = OCCMap->Find(*edge);
03201 
03202       OCCMap->UnBind(*edge);
03203 
03204       if(!OccToCGM->erase(k))
03205         PRINT_WARNING("The OccCurve and iCreatedTotal pair is not in the map!");
03206     }
03207   CurveList->remove(fcurve); 
03208   if(!edge->IsNull())
03209     edge->Nullify();
03210   return CUBIT_SUCCESS;
03211 }
03212 //-------------------------------------------------------------------------
03213 // Purpose       : Delete a OCCPoint and child entities.
03214 //
03215 // Special Notes :
03216 //
03217 // Creator       : Jason Kraftcheck
03218 //
03219 // Creation Date : 09/29/03
03220 //-------------------------------------------------------------------------
03221 CubitStatus
03222 OCCQueryEngine::delete_solid_model_entities( TBPoint* point) const
03223 {
03224   OCCPoint* fpoint = dynamic_cast<OCCPoint*>(point);
03225   if (!fpoint)
03226     return CUBIT_FAILURE;
03227 
03228   if(fpoint->num_curves() > 0)
03229     return CUBIT_FAILURE;
03230 
03231   CubitStatus stat = unhook_Point_from_OCC(point);
03232   
03233   if(stat)
03234     delete point;
03235   return stat;
03236 }
03237 
03238 //-------------------------------------------------------------------------
03239 // Purpose       : unhook a Point from its underlining OCC entity.
03240 //
03241 // Special Notes :
03242 //
03243 // Creator       : Jane Hu
03244 //
03245 // Creation Date : 12/12/07
03246 //-------------------------------------------------------------------------
03247 CubitStatus
03248 OCCQueryEngine::unhook_Point_from_OCC( TBPoint* point) const 
03249 {
03250   OCCPoint* fpoint = dynamic_cast<OCCPoint*>(point);
03251   if (!fpoint)
03252     return CUBIT_FAILURE;
03253 
03254   TopoDS_Vertex* vertex = fpoint->get_TopoDS_Vertex();
03255   if (!vertex)
03256     return CUBIT_FAILURE;
03257 
03258   //remove the entry from label tree
03259   OCCAttribSet::remove_attribute(*vertex) ;
03260 
03261   //remove the entry from the map
03262   int k;
03263   if(OCCMap->IsBound(*vertex))
03264     {
03265       k = OCCMap->Find(*vertex);
03266 
03267       OCCMap->UnBind(*vertex);
03268 
03269       if(!OccToCGM->erase(k))
03270         PRINT_ERROR("The OccPoint and iCreatedTotal pair is not in the map!");
03271     }
03272   if(!vertex->IsNull())
03273     vertex->Nullify();
03274   return CUBIT_SUCCESS;
03275 }
03276 
03277 
03278 //-------------------------------------------------------------------------
03279 // Purpose       : fire a ray at the specified body, returning the entities hit.
03280 //
03281 // Special Notes :
03282 //
03283 // Creator       : Jane Hu
03284 //
03285 // Creation Date : 12/12/07
03286 //-------------------------------------------------------------------------
03287 CubitStatus OCCQueryEngine::fire_ray(  CubitVector &origin,
03288                         CubitVector &direction,
03289                         DLIList<TopologyBridge*> &at_entity_list,
03290                         DLIList<double> &ray_params,
03291                         int max_hits ,
03292                         double ray_radius ,
03293                         DLIList<TopologyBridge*> *hit_entity_list_ptr )const
03294 {
03295   CubitStatus status = CUBIT_SUCCESS;
03296 
03297   //- fire a ray at the specified body, returning the entities hit and
03298   //- the parameters along the ray; return CUBIT_FAILURE if error
03299   // - line body intersection. 
03300   gp_Pnt p(origin.x(), origin.y(), origin.z());
03301   gp_Dir dir(direction.x(), direction.y(), direction.z());
03302   gp_Lin L(p, dir);
03303   TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(L); 
03304   
03305   for(int i = 0; i < at_entity_list.size(); i++)
03306   {
03307     TopologyBridge* tb = at_entity_list.get_and_step();
03308     TopoDS_Shape *shape;
03309     OCCBody *occBody = CAST_TO(tb, OCCBody);
03310     if (occBody )
03311     {
03312       occBody->get_TopoDS_Shape(shape);
03313     
03314       BRepExtrema_DistShapeShape distShapeShape(edge, *shape);
03315       //distShapeShape.Perform();
03316       if (!distShapeShape.IsDone())
03317       {
03318         PRINT_ERROR("Cannot calculate the intersection points for the input body.\n");
03319         return CUBIT_FAILURE;
03320       }
03321 
03322       if (distShapeShape.Value() < get_sme_resabs_tolerance())
03323       {
03324         int numPnt = distShapeShape.NbSolution();
03325         for (int i = 1; i <= numPnt; i++)
03326         {
03327       double para;
03328       distShapeShape.ParOnEdgeS1(i , para);
03329       ray_params.append(para);
03330         }
03331         hit_entity_list_ptr->append(tb);
03332       } 
03333     }
03334   }
03335   return status;
03336 }
03337 
03338 double OCCQueryEngine::get_sme_resabs_tolerance() const
03339 {
03340   return Precision::Confusion(); 
03341 }
03342 // Gets solid modeler's resolution absolute tolerance
03343 
03344 double OCCQueryEngine::set_sme_resabs_tolerance( double p)
03345 {
03346   double old_p = get_sme_resabs_tolerance();
03347   BRepBuilderAPI::Precision(p);
03348   return old_p;
03349 }
03350 
03351 CubitStatus OCCQueryEngine::set_int_option( const char* , int )
03352 {
03353   PRINT_ERROR("OCCQueryEngine::set_int_option not yet implemented.\n");
03354   return CUBIT_FAILURE;
03355 }
03356 
03357 CubitStatus OCCQueryEngine::set_dbl_option( const char* , double )
03358 {
03359   PRINT_ERROR("OCCQueryEngine::set_dbl_option not yet implemented.\n");
03360   return CUBIT_FAILURE;
03361 }
03362 
03363 CubitStatus OCCQueryEngine::set_str_option( const char* , const char* )
03364 {
03365   PRINT_ERROR("OCCQueryEngine::set_str_option not yet implemented.\n");
03366   return CUBIT_FAILURE;
03367 }
03368 //- Set solid modeler options
03369 
03370 
03371 //===========================================================================
03372 //Function Name: ensure_is_ascii_stl_file
03373 //Member Type:
03374 //Description: returns CUBIT_TRUE in is_ascii if fp is an ascii stl file
03375 //Author: Plamen Stoyanov (USF)
03376 //===========================================================================
03377 CubitStatus OCCQueryEngine::ensure_is_ascii_stl_file(FILE * fp, CubitBoolean &is_ascii)
03378 {
03379 
03380   char line[128]="";
03381 
03382   if (fgets(line, 128, fp)==NULL)
03383     {
03384       return CUBIT_FAILURE;
03385     }
03386   if (fgets(line, 128, fp)==NULL)
03387     {
03388       return CUBIT_FAILURE;
03389     }
03390   if (strlen(line)==127)
03391     {
03392       if (fgets(line, 128, fp)==NULL)
03393     {
03394       return CUBIT_FAILURE;
03395     }
03396     }
03397 
03398 
03399   unsigned int dummy_int=0;
03400 
03401   while (isspace(line[dummy_int])&& dummy_int<strlen(line)) dummy_int++;
03402 
03403   if (strlen(line)-dummy_int>5)
03404     {
03405       if (tolower(line[dummy_int++])=='f' &&
03406       tolower(line[dummy_int++])=='a' &&
03407       tolower(line[dummy_int++])=='c' &&
03408       tolower(line[dummy_int++])=='e' &&
03409       tolower(line[dummy_int])=='t')
03410     {
03411       if (fgets(line, 128, fp)==NULL)
03412         {
03413           return CUBIT_FAILURE;
03414         }
03415       dummy_int=0;
03416       while (isspace(line[dummy_int])&& dummy_int<strlen(line))
03417         {
03418           dummy_int++;
03419         }
03420       if (strlen(line)-dummy_int>5)
03421         {
03422           if (tolower(line[dummy_int++])=='o' &&
03423           tolower(line[dummy_int++])=='u' &&
03424           tolower(line[dummy_int++])=='t' &&
03425           tolower(line[dummy_int++])=='e' &&
03426           tolower(line[dummy_int])=='r')
03427         {
03428           if (fgets(line, 128, fp)==NULL)
03429             {
03430               return CUBIT_FAILURE;
03431             }
03432           dummy_int=0;
03433           while (isspace(line[dummy_int])&& dummy_int<strlen(line)) {
03434             dummy_int++;
03435           }
03436           if (strlen(line)-dummy_int>6)
03437             {
03438               if (tolower(line[dummy_int++])=='v' &&
03439               tolower(line[dummy_int++])=='e' &&
03440               tolower(line[dummy_int++])=='r' &&
03441               tolower(line[dummy_int++])=='t' &&
03442               tolower(line[dummy_int++])=='e'   &&
03443               tolower(line[dummy_int])=='x')
03444             {
03445               is_ascii=CUBIT_TRUE;
03446             }
03447             }
03448         }
03449         }
03450     }
03451     }
03452   return CUBIT_SUCCESS;
03453 }
03454 
03455 
03456 //=============================================================================
03457 //Function:   create_super_facet_bounding_box(PUBLIC)
03458 //Description: Find the bounding box of a list of BodySMs
03459 //Author: jdfowle
03460 //Date: 12/15/03
03461 //=============================================================================
03462 CubitStatus OCCQueryEngine::create_super_bounding_box(
03463                               DLIList<BodySM*>& body_list,
03464                               CubitBox& super_box )
03465 {
03466   BodySM *bodySM;
03467   int i;
03468   CubitStatus status = CUBIT_SUCCESS;
03469 
03470   body_list.reset();
03471   for ( i = 0; i < body_list.size(); i++ ) {
03472     bodySM = body_list.get_and_step();  
03473     OCCBody* occBody = CAST_TO(bodySM, OCCBody);
03474     super_box |= occBody->get_bounding_box();
03475   }
03476 
03477   return status;
03478 }
03479 
03480 CubitStatus OCCQueryEngine::restore_transform( BodySM* body )
03481 {
03482   return CUBIT_FAILURE;
03483 }
03484 
03485 CubitStatus OCCQueryEngine::translate( BodySM* body, const CubitVector& d )
03486 {
03487   OCCBody* theBody = dynamic_cast<OCCBody*>(body);
03488   return theBody ? theBody->move( d.x(), d.y(), d.z() ) : CUBIT_FAILURE;
03489 }
03490 CubitStatus OCCQueryEngine::rotate( BodySM* body, const CubitVector& v, double a )
03491 {
03492   // a is in degree.
03493   OCCBody* occ_bod = dynamic_cast<OCCBody*>(body);
03494   a *= CUBIT_PI/180;
03495   return occ_bod ? occ_bod->rotate( v.x(), v.y(), v.z(), a ) : CUBIT_FAILURE;
03496 }
03497 CubitStatus OCCQueryEngine::scale( BodySM* body, double factor )
03498 {
03499   OCCBody* facetbod = dynamic_cast<OCCBody*>(body);
03500   return facetbod ? facetbod->scale( factor ) : CUBIT_FAILURE;
03501 }
03502 CubitStatus OCCQueryEngine::scale( BodySM* body, const CubitVector& f )
03503 {
03504   OCCBody* facetbod = dynamic_cast<OCCBody*>(body);
03505   return facetbod ? facetbod->scale( f.x(), f.y(), f.z() ) : CUBIT_FAILURE;
03506 }
03507 
03508 //-------------------------------------------------------------------------
03509 // Purpose       : Transform a Solid, Surface, Curve, or Vertex
03510 //
03511 // Special Notes :
03512 //
03513 // Creator       : Jane Hu
03514 //
03515 // Creation Date : 10/23/07
03516 //-------------------------------------------------------------------------
03517 CubitStatus OCCQueryEngine::translate( GeometryEntity* entity,
03518                                        const CubitVector& v )
03519 {
03520   TopoDS_Shape * shape;
03521   if ((shape = get_TopoDS_Shape_of_entity(entity)) == NULL)
03522     {
03523       PRINT_ERROR( "problem occured getting OCC entity.\n"
03524            "       Aborting.\n" );
03525       return CUBIT_FAILURE;
03526     }
03527 
03528   gp_Vec aVec(v.x(), v.y(),v.z());
03529   gp_Trsf aTrsf;  
03530   aTrsf.SetTranslation(aVec);
03531 
03532   BRepBuilderAPI_Transform aBRepTrsf(*shape, aTrsf);
03533   
03534   update_entity_shape(entity, &aBRepTrsf);
03535   return CUBIT_SUCCESS;
03536 }
03537 
03538 CubitStatus OCCQueryEngine::update_entity_shape(GeometryEntity* entity_ptr,
03539                     BRepBuilderAPI_ModifyShape* aBRepTrsf,
03540                                         BRepAlgoAPI_BooleanOperation *op)
03541 {
03542   if (OCCBody *body_ptr = CAST_TO( entity_ptr, OCCBody))
03543     {
03544       body_ptr->update_OCC_entity(aBRepTrsf, op);
03545       return CUBIT_SUCCESS;
03546     }
03547 
03548   else if( OCCSurface *surface_ptr = CAST_TO( entity_ptr, OCCSurface))
03549     {
03550       surface_ptr->update_OCC_entity(aBRepTrsf, op);
03551       return CUBIT_SUCCESS;
03552     }
03553 
03554   else if( OCCCurve *curve_ptr = CAST_TO( entity_ptr, OCCCurve))
03555     {
03556        curve_ptr->update_OCC_entity(aBRepTrsf, op); 
03557        return CUBIT_SUCCESS;
03558     }
03559 
03560   else if( OCCPoint *point_ptr = CAST_TO( entity_ptr, OCCPoint))
03561     {
03562       point_ptr->update_OCC_entity(aBRepTrsf, op);
03563       return CUBIT_SUCCESS;
03564     }
03565 
03566   PRINT_ERROR("Non-OCC TopologyBridge at %s:%d.\n", __FILE__, __LINE__ );
03567   return CUBIT_FAILURE;
03568 }
03569 
03570 //a is angular value of rotation in radians
03571 CubitStatus OCCQueryEngine::rotate( GeometryEntity* entity,
03572                                     const CubitVector& v, double a )
03573 {
03574   TopoDS_Shape * shape;
03575   if ((shape = get_TopoDS_Shape_of_entity(entity)) == NULL)
03576     {
03577       PRINT_ERROR( "problem occured getting OCC entity.\n"
03578            "       Aborting.\n" );
03579       return CUBIT_FAILURE;
03580     }
03581 
03582   gp_Pnt aOrigin(0,0,0);
03583   gp_Dir aDir(v.x(), v.y(), v.z());
03584   gp_Ax1 anAxis(aOrigin, aDir);
03585 
03586   //a is angular value of rotation in radians 
03587   gp_Trsf aTrsf;
03588   aTrsf.SetRotation(anAxis, a);
03589 
03590   BRepBuilderAPI_Transform aBRepTrsf(*shape, aTrsf);
03591   update_entity_shape(entity, &aBRepTrsf);
03592   return CUBIT_SUCCESS;
03593 }
03594 
03595 CubitStatus OCCQueryEngine::scale( GeometryEntity* entity, double f )
03596 {
03597   TopoDS_Shape * shape;
03598   if ((shape = get_TopoDS_Shape_of_entity(entity)) == NULL)
03599     {
03600       PRINT_ERROR( "problem occured getting OCC entity.\n"
03601            "       Aborting.\n" );
03602       return CUBIT_FAILURE;
03603     }
03604 
03605   gp_Trsf aTrsf;
03606   aTrsf.SetScaleFactor(f);
03607 
03608   BRepBuilderAPI_Transform aBRepTrsf(*shape, aTrsf);
03609   update_entity_shape(entity, &aBRepTrsf);
03610   return CUBIT_SUCCESS;
03611 }
03612 
03613 CubitStatus OCCQueryEngine::scale( GeometryEntity* entity, 
03614                                    const CubitVector& v )
03615 {
03616   TopoDS_Shape * shape;
03617   if ((shape = get_TopoDS_Shape_of_entity(entity)) == NULL)
03618     {
03619       PRINT_ERROR( "problem occured getting OCC entity.\n"
03620                    "       Aborting.\n" );
03621       return CUBIT_FAILURE;
03622     }
03623 
03624   gp_GTrsf gTrsf;
03625   gTrsf.SetValue(1,1, v.x());
03626   gTrsf.SetValue(2,2, v.y());
03627   gTrsf.SetValue(3,3, v.z());
03628 
03629   BRepBuilderAPI_GTransform gBRepTrsf(gTrsf);
03630   gBRepTrsf.Perform(*shape);
03631   update_entity_shape(entity, &gBRepTrsf);
03632   return CUBIT_SUCCESS;
03633 }
03634 
03635 // like other engines here v is the normal of symmetric plane.
03636 CubitStatus OCCQueryEngine::reflect( GeometryEntity* entity, 
03637                                      const CubitVector&  v)
03638 {
03639   TopoDS_Shape * shape;
03640   if ((shape = get_TopoDS_Shape_of_entity(entity)) == NULL)
03641     {
03642       PRINT_ERROR( "problem occured getting OCC entity.\n"
03643            "       Aborting.\n" );
03644       return CUBIT_FAILURE;
03645     }
03646  
03647   gp_Pnt aOrigin(0,0,0);
03648   gp_Dir aDir(v.x(), v.y(), v.z());
03649   gp_Ax2 anAx2(aOrigin, aDir);
03650 
03651   gp_Trsf aTrsf;
03652   aTrsf.SetMirror(anAx2);
03653 
03654   BRepBuilderAPI_Transform aBRepTrsf(*shape, aTrsf);
03655   update_entity_shape(entity, &aBRepTrsf);
03656   return CUBIT_SUCCESS;
03657 }
03658 
03659 //===============================================================================
03660 // Function   : bodies_overlap
03661 // Member Type: PUBLIC
03662 // Description: determine if OCC-based bodies overlap
03663 // Author     : Jane Hu 
03664 // Date       : 10/07
03665 //===============================================================================
03666 CubitBoolean OCCQueryEngine::bodies_overlap (BodySM * body_ptr_1,
03667                                              BodySM * body_ptr_2 ) const
03668 {
03669   OCCBody *occ_body1 = CAST_TO(body_ptr_1, OCCBody);
03670   if (!occ_body1)
03671     {
03672       PRINT_ERROR("Can't calculate intersection of non-OCC bodies.");
03673       return CUBIT_FALSE;
03674     }
03675  
03676   OCCBody *occ_body2 = CAST_TO(body_ptr_2, OCCBody);
03677   if (!occ_body2)
03678     {
03679       PRINT_ERROR("Can't calculate intersection of non-OCC bodies.");
03680       return CUBIT_FALSE;
03681     }
03682 
03683   CubitBox box_1 = occ_body1->get_bounding_box();
03684   CubitBox box_2 = occ_body2->get_bounding_box();
03685   if ( !box_1.overlap( GEOMETRY_RESABS, box_2 ) )
03686     return CUBIT_FALSE;
03687 
03688   TopoDS_Shape *shape1;
03689   occ_body1->get_TopoDS_Shape(shape1);
03690   TopoDS_Shape *shape2;
03691   occ_body2->get_TopoDS_Shape(shape2); 
03692   
03693   //BRepAlgoAPI_Section calculates intersection between faces only.
03694   TopExp_Explorer Ex1, Ex2;
03695   for (Ex1.Init(*shape1, TopAbs_SOLID); Ex1.More(); Ex1.Next())
03696     {
03697       TopoDS_Solid *posolid1 =  new TopoDS_Solid;
03698       *posolid1 = TopoDS::Solid(Ex1.Current());
03699       OCCLump * lump1 = new OCCLump(posolid1); 
03700       for (Ex2.Init(*shape2, TopAbs_SOLID); Ex2.More(); Ex2.Next())
03701     {
03702       TopoDS_Solid *posolid2 =  new TopoDS_Solid;
03703       *posolid2 = TopoDS::Solid(Ex2.Current());
03704       OCCLump * lump2 = new OCCLump(posolid2);
03705       CubitBoolean is_overlap = volumes_overlap(lump1, lump2);
03706       if(is_overlap)
03707         return CUBIT_TRUE;
03708     }
03709     }
03710   return CUBIT_FALSE;
03711 }
03712 
03713 CubitBoolean OCCQueryEngine::volumes_overlap (Lump *lump1, Lump *lump2 ) const
03714 {
03715   OCCLump *occ_lump1 = CAST_TO(lump1, OCCLump);
03716   if (!occ_lump1)
03717     {
03718       PRINT_ERROR("Can't calculate intersection of non-OCC solids.");
03719       return CUBIT_FALSE;
03720     }
03721 
03722   OCCLump *occ_lump2 = CAST_TO(lump2, OCCLump);
03723   if (!occ_lump2)
03724     {
03725       PRINT_ERROR("Can't calculate intersection of non-OCC solids.");
03726       return CUBIT_FALSE;
03727     }
03728 
03729   CubitBox box_1 = occ_lump1->bounding_box();
03730   CubitBox box_2 = occ_lump2->bounding_box();
03731   if ( !box_1.overlap( GEOMETRY_RESABS, box_2 ) )
03732     return CUBIT_FALSE;
03733 
03734   TopoDS_Shape *shape1 = (TopoDS_Shape*)(occ_lump1->get_TopoDS_Solid());
03735   TopoDS_Shape *shape2 = (TopoDS_Shape*)(occ_lump2->get_TopoDS_Solid());
03736   
03737   //BRepAlgoAPI_Section calculates intersection between faces only.
03738   TopExp_Explorer Ex1, Ex2;
03739   for (Ex1.Init(*shape1, TopAbs_FACE); Ex1.More(); Ex1.Next())  
03740     {
03741       for (Ex2.Init(*shape2, TopAbs_FACE); Ex2.More(); Ex2.Next()) 
03742     {
03743       BRepAlgoAPI_Section section(Ex1.Current(), Ex2.Current());
03744       if (section.HasGenerated())
03745         return CUBIT_TRUE;
03746     }
03747     }
03748   return CUBIT_FALSE;
03749 }
03750 
03751 void OCCQueryEngine::copy_attributes(TopoDS_Shape& old_shape,
03752                                      TopoDS_Shape& new_shape)
03753 {
03754   if(new_shape.IsNull())
03755     return;
03756 
03757   //update the attribute label tree
03758   DLIList<CubitSimpleAttrib> list;
03759   OCCAttribSet::get_attributes(old_shape, list);
03760 
03761   for(int i = 0; i < list.size(); i ++)
03762   {
03763     const CubitSimpleAttrib& s_attr = list.get_and_step();
03764     TopAbs_ShapeEnum type = old_shape.ShapeType();
03765     if(new_shape.ShapeType() < type)
03766     {
03767       TopTools_IndexedMapOfShape M;
03768       TopExp::MapShapes(new_shape, type, M); 
03769       for(int j = 1; j <= M.Extent() ; j++ )
03770       {
03771         TopoDS_Shape sub_shape = M(j);
03772         OCCAttribSet::append_attribute(s_attr, sub_shape); 
03773       }
03774     }
03775     else    
03776       OCCAttribSet::append_attribute(s_attr, new_shape);
03777   }
03778 }
03779 
03780 int OCCQueryEngine::update_OCC_map(TopoDS_Shape& old_shape, 
03781                                    TopoDS_Shape& new_shape)
03782 {
03783   if (old_shape.IsNull() || !OCCMap->IsBound(old_shape) || 
03784       old_shape.IsEqual(new_shape))
03785     return -1;
03786 
03787   //update the attribute label tree
03788   int current_id = OCCMap->Find(old_shape);
03789   std::map<int, TDF_Label>::iterator it_lab =
03790           Shape_Label_Map->find(current_id);
03791   CubitBoolean newlyBound = CUBIT_FALSE;
03792   TopTools_IndexedMapOfShape M;
03793   TopoDS_Shape new_subshape;
03794   new_subshape.Nullify();
03795 
03796   if(old_shape.ShapeType() == TopAbs_SOLID)
03797     TopExp::MapShapes(new_shape, TopAbs_SOLID, M);
03798   else if (old_shape.ShapeType() == TopAbs_SHELL)
03799     TopExp::MapShapes(new_shape, TopAbs_SHELL, M);
03800   else if (old_shape.ShapeType() == TopAbs_FACE)
03801     TopExp::MapShapes(new_shape, TopAbs_FACE, M);
03802 
03803   if(it_lab != Shape_Label_Map->end())
03804   {
03805      CubitBoolean isNewShapeBound = CUBIT_FALSE;
03806      if(old_shape.ShapeType() > TopAbs_COMPOUND && !new_shape.IsNull() &&
03807         new_shape.ShapeType() == TopAbs_COMPOUND && M.Extent() == 1)
03808      {
03809        new_subshape = M(1); 
03810        isNewShapeBound = OCCMap->IsBound(new_subshape);
03811        copy_attributes(old_shape, new_subshape);
03812        Shape_Label_Map->erase(current_id);
03813        if(isNewShapeBound != OCCMap->IsBound(new_subshape)) 
03814          newlyBound = CUBIT_TRUE;
03815      }
03816      else
03817      {
03818        isNewShapeBound = OCCMap->IsBound(new_shape);
03819        copy_attributes(old_shape, new_shape);
03820        Shape_Label_Map->erase(current_id);
03821        if(isNewShapeBound != OCCMap->IsBound(new_shape))
03822          newlyBound = CUBIT_TRUE; 
03823      }
03824   }
03825 
03826   //update CGM-OCC map
03827   int k = current_id;
03828   assert (k > 0 && k <= iTotalTBCreated);
03829 
03830   std::map<int, TopologyBridge*>::iterator it = OccToCGM->find(k);
03831   TopologyBridge* tb = NULL;
03832   if (it != OccToCGM->end()) 
03833      tb = (*it).second;
03834 
03835   //unless just changing location, if the TShape is going to change, remove
03836   //old curve_list .
03837   CubitBoolean curve_removed = CUBIT_FALSE;
03838   if(old_shape.ShapeType() == TopAbs_VERTEX && !new_shape.IsPartner(old_shape)) 
03839   {
03840     //remove the curve list associated with the vertex too.
03841     GeometryEntity* ge =  CAST_TO(tb, GeometryEntity);
03842     if (ge)
03843     {
03844       OCCPoint* test_p = CAST_TO(ge, OCCPoint);
03845       if(test_p)
03846       {
03847         test_p->clear_curves();
03848         curve_removed = CUBIT_TRUE;
03849       }
03850     }
03851   }
03852 
03853   OCCMap->UnBind(old_shape);
03854   if(new_subshape.IsNull())
03855     new_subshape = new_shape;
03856 
03857   if (tb && TopAbs_SOLID == old_shape.ShapeType() && !new_shape.IsNull() && 
03858        TopAbs_COMPOUND == new_shape.ShapeType() && M.Extent() > 1)
03859   {
03860     OccToCGM->erase(k);
03861     GeometryEntity* ge =  CAST_TO(tb, GeometryEntity);
03862     if(ge)
03863       delete_solid_model_entities( ge, CUBIT_TRUE);
03864     return k;
03865   }
03866 
03867   else if(tb && TopAbs_FACE == old_shape.ShapeType() && !new_shape.IsNull() &&
03868        TopAbs_COMPOUND == new_shape.ShapeType() && M.Extent() > 1)
03869   {
03870     GeometryEntity* ge =  CAST_TO(tb, GeometryEntity);
03871     if(ge)
03872     {
03873       OCCSurface *face = CAST_TO(ge, OCCSurface);
03874       OCCShell* shell = face->my_shell();
03875       if (shell)
03876       {
03877         TopoDS_Shell* shape = shell->get_TopoDS_Shell();
03878         assert(!shape );
03879         if (shape) {
03880           PRINT_ERROR("Unexpected non-NULL TopoDS_Shell pointer.\n");
03881           return -1;
03882         }
03883       }
03884       OCCLump* lump = face->my_lump();
03885       if(lump)
03886       {
03887         TopoDS_Solid* shape = lump->get_TopoDS_Solid();
03888         assert(!shape );
03889         if (shape) {
03890           PRINT_ERROR("Unexpected non-NULL TopoDS_Solid pointer.\n");
03891           return -1;
03892         }
03893         delete lump;
03894       }
03895       OCCBody* body = face->my_body();
03896       if (body)
03897         delete body;
03898       
03899       delete_solid_model_entities(ge, CUBIT_TRUE); 
03900       if(shell)
03901         delete shell;
03902     }
03903     return k;
03904   }
03905 
03906   else if (tb && ((!new_subshape.IsNull() && !old_shape.IsSame(new_subshape)&&
03907         OCCMap->IsBound(new_subshape) && 
03908         OccToCGM->find(OCCMap->Find(new_subshape))!= OccToCGM->end()) || 
03909         new_subshape.IsNull()))
03910   //already has a TB built on new_shape
03911   {
03912     //delete the second TB corresponding to old_shape
03913     OccToCGM->erase(k);
03914     GeometryEntity* ge =  CAST_TO(tb, GeometryEntity);
03915     if(ge)
03916     {
03917       //PRINT_INFO("TB: %p\n",ge);
03918       Lump* lump = CAST_TO(ge, Lump);
03919       if(lump)
03920       {
03921         BodySM* body = CAST_TO(lump,OCCLump)->get_body();
03922         if(body)
03923         {
03924           //OCCBody* occ_body = CAST_TO(body, OCCBody);
03925           //TopoDS_Compound* pshape = occ_body->get_TopoDS_Shape(); 
03926           //if(!pshape || pshape->IsNull())
03927           delete_solid_model_entities(body);
03928         }
03929       }
03930 
03931       else
03932       {
03933         OCCPoint* test_p = CAST_TO(ge, OCCPoint);
03934         if(test_p)
03935           test_p->clear_curves();
03936         delete_solid_model_entities( ge, CUBIT_FALSE );
03937       }
03938     }
03939 
03940     else
03941     {
03942       ShellSM * shell = CAST_TO(tb, ShellSM);
03943       if(shell)
03944       {
03945         DLIList<OCCSurface*> memberSurfaces;
03946         OCCShell* occShell = CAST_TO(shell, OCCShell);
03947         memberSurfaces = occShell->getMemberSurfaces();
03948         while (memberSurfaces.size())
03949         {
03950           OCCSurface* memberSurf = memberSurfaces.pop();
03951           if (SurfaceList->is_in_list(memberSurf))
03952             // if the surface has not been unhooked and deleted
03953             memberSurf->set_shell((OCCShell*)NULL);
03954         }
03955 
03956         OCCLump* lump = CAST_TO(shell, OCCShell)->my_lump();
03957         if(lump && (lump->get_TopoDS_Solid() == NULL || 
03958            !OCCMap->IsBound(*(lump->get_TopoDS_Solid()))))
03959         {
03960           delete CAST_TO(shell, OCCShell)->my_body();
03961           delete lump;
03962         }
03963         unhook_ShellSM_from_OCC(shell);
03964         delete shell;
03965         return k;
03966       }
03967       LoopSM* loop = CAST_TO(tb, LoopSM);
03968       if(loop)
03969       {
03970          DLIList<OCCCoEdge*> children;
03971          children = CAST_TO(loop, OCCLoop)->coedges();
03972          while(children.size())
03973          {
03974            OCCCoEdge* coedge = children.pop();
03975            CAST_TO(coedge->curve(), OCCCurve)->remove_loop(CAST_TO(loop, OCCLoop));
03976            delete (OCCCoEdge*)coedge;
03977          }
03978          unhook_LoopSM_from_OCC(loop);
03979          delete loop;
03980          return k;
03981       }
03982     }
03983   }
03984 
03985   else
03986   {   
03987     //if the new_shape is bounded in copy_attribute, unbind it and rebind to 
03988     //the old k
03989     if(newlyBound)
03990     {
03991       int new_k = OCCMap->Find(new_subshape);
03992       TDF_Label aLabel;
03993       CubitBoolean found = CUBIT_FALSE;
03994       OCCAttribSet::FindShape(new_subshape, aLabel, found);
03995       assert(found);
03996       Shape_Label_Map->erase(new_k);
03997       Shape_Label_Map->insert(labType(k, aLabel)); 
03998       OCCMap->UnBind(new_subshape);
03999     }      
04000     if(!OCCMap->IsBound(new_subshape))
04001       OCCMap->Bind(new_subshape, k);
04002     if(tb && !curve_removed)
04003       set_TopoDS_Shape(tb, new_subshape);
04004   }
04005   return k;
04006 }
04007 
04008 void OCCQueryEngine::unhook_coedges_of_a_curve(OCCCurve* curve,
04009                                                OCCLoop* loop)const 
04010 {
04011   DLIList<OCCCoEdge*> coedges;
04012   DLIList<OCCCoEdge *> children ;
04013   if (loop != NULL)
04014     children = loop->coedges();
04015   else
04016   {
04017     DLIList<OCCLoop*> loops;
04018     loops = curve->loops();
04019     for (int i = 0; i < loops.size(); i ++)
04020       children += loops.get_and_step()->coedges();
04021   } 
04022   for(int j = 0; j < children.size(); j++)
04023   {
04024      OCCCoEdge* coedge = children.get_and_step();
04025      if (coedge->curve() == curve)
04026        coedges.append(coedge);
04027   }
04028   unhook_CoEdges_from_OCC(coedges);
04029 }
04030 
04031 void OCCQueryEngine::set_TopoDS_Shape(TopologyBridge* tb,
04032                                       TopoDS_Shape& shape)
04033 {
04034   BodySM* body = CAST_TO(tb, BodySM);
04035   if(body)
04036     return CAST_TO(body, OCCBody)->set_TopoDS_Shape(TopoDS::Compound(shape));
04037 
04038   Lump* lump = CAST_TO(tb, Lump);
04039   if(lump)
04040     return CAST_TO(lump, OCCLump)->set_TopoDS_Solid(TopoDS::Solid(shape));
04041 
04042   ShellSM* shell = CAST_TO(tb, ShellSM);
04043   if(shell)
04044     return CAST_TO(shell, OCCShell)->set_TopoDS_Shell(TopoDS::Shell(shape));
04045 
04046   Surface* surface = CAST_TO(tb, Surface);
04047   if (surface)
04048     return CAST_TO(surface, OCCSurface)->set_TopoDS_Face(TopoDS::Face(shape));
04049 
04050   LoopSM* loop =  CAST_TO(tb, LoopSM);
04051   if(loop)
04052     return CAST_TO(loop, OCCLoop)->set_TopoDS_Wire(TopoDS::Wire(shape));
04053 
04054   Curve* curve = CAST_TO(tb, Curve);
04055   if (curve)
04056     return CAST_TO(curve, OCCCurve)->set_TopoDS_Edge(TopoDS::Edge(shape));
04057 
04058   TBPoint* point = CAST_TO(tb, TBPoint);
04059   if(point)
04060     return CAST_TO(point, OCCPoint)->set_TopoDS_Vertex(TopoDS::Vertex(shape));
04061   
04062 }
04063 
04064 //Added by Jane Hu on 06/17/11
04065 void OCCQueryEngine::bound_TopoDS_Shape(const TopoDS_Shape & aShape)
04066 {
04067   (iTotalTBCreated)++;
04068   switch (aShape.ShapeType())
04069   {
04070     case TopAbs_COMPOUND:
04071       OCCMap->Bind(TopoDS::Compound(aShape), iTotalTBCreated); 
04072       break;
04073     case TopAbs_SOLID:
04074       OCCMap->Bind(TopoDS::Solid(aShape), iTotalTBCreated);
04075       break;
04076     case TopAbs_SHELL:
04077       OCCMap->Bind(TopoDS::Shell(aShape), iTotalTBCreated);
04078       break;
04079     case TopAbs_FACE: 
04080       OCCMap->Bind(TopoDS::Face(aShape), iTotalTBCreated);
04081       break;
04082     case TopAbs_WIRE:
04083       OCCMap->Bind(TopoDS::Wire(aShape), iTotalTBCreated);
04084       break;
04085     case TopAbs_EDGE:
04086       OCCMap->Bind(TopoDS::Edge(aShape), iTotalTBCreated);
04087       break;
04088     case TopAbs_VERTEX:
04089       OCCMap->Bind(TopoDS::Vertex(aShape), iTotalTBCreated);
04090       break;
04091 
04092     default:
04093       (iTotalTBCreated)--;
04094   }
04095 }
04096 //EOF
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines