cgma
OCCCurve.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : OCCCurve.cpp
00003 //
00004 // Purpose       : 
00005 //
00006 // Special Notes :
00007 //
00008 // Creator       : Steven J. Owen
00009 //
00010 // Creation Date : 07/14/00
00011 //
00012 // Owner         : Steven J. Owen
00013 //-------------------------------------------------------------------------
00014 
00015 // ********** BEGIN STANDARD INCLUDES      **********
00016 
00017 // ********** END STANDARD INCLUDES        **********
00018 // ********** BEGIN CUBIT INCLUDES         **********
00019 
00020 #include "CastTo.hpp"
00021 #include "CubitVector.hpp"
00022 #include "CubitBox.hpp"
00023 #include "GeometryDefines.h"
00024 #include "OCCCurve.hpp"
00025 #include "GeometryQueryEngine.hpp"
00026 #include "OCCQueryEngine.hpp"
00027 #include "CoEdgeSM.hpp"
00028 
00029 #include "OCCBody.hpp"
00030 #include "OCCLump.hpp"
00031 #include "OCCShell.hpp"
00032 #include "OCCSurface.hpp"
00033 #include "OCCLoop.hpp"
00034 #include "OCCCoEdge.hpp"
00035 #include "OCCPoint.hpp"
00036 #include "OCCAttribSet.hpp"
00037 
00038 #include <BRepAdaptor_Curve.hxx>
00039 #include <TopExp.hxx>
00040 #include "GProp_GProps.hxx"
00041 #include "BRepGProp.hxx"
00042 #include <TopTools_IndexedMapOfShape.hxx>
00043 #include "TopTools_ListIteratorOfListOfShape.hxx"
00044 #include <GCPnts_AbscissaPoint.hxx>
00045 #include <Bnd_Box.hxx>
00046 #include <BndLib_Add3dCurve.hxx>
00047 #include <Precision.hxx>
00048 #include <Extrema_ExtPC.hxx>
00049 #include <BRepLProp_CLProps.hxx>
00050 #include <BRep_Tool.hxx>
00051 #include <TopoDS.hxx>
00052 #include "BRepBuilderAPI_MakeEdge.hxx"
00053 #include "Geom_BezierCurve.hxx"
00054 #include "Geom_BSplineCurve.hxx"
00055 #include "GeomAPI_ProjectPointOnCurve.hxx"
00056 #include "TColgp_Array1OfPnt.hxx"
00057 #include "GeomAdaptor_Curve.hxx"
00058 #include "GCPnts_QuasiUniformAbscissa.hxx"
00059 #include "BRepAlgoAPI_BooleanOperation.hxx"
00060 #include "TopTools_ListOfShape.hxx"
00061 #include "BRepAlgo_NormalProjection.hxx"
00062 #include "TopExp_Explorer.hxx"
00063 #include "GeomLProp_CurveTool.hxx"
00064 #include "GeomAPI_ExtremaCurveCurve.hxx"
00065 #include "Geom_Line.hxx"
00066 #include "Geom_Circle.hxx"
00067 #include "Geom_Ellipse.hxx"
00068 #include "GC_MakeLine.hxx"
00069 #include "gp_Circ.hxx"
00070 #include "gp_Elips.hxx"
00071 #include "BRepBuilderAPI_Transform.hxx"
00072 #include "BRepBuilderAPI_GTransform.hxx"
00073 #include "BRepBuilderAPI_ModifyShape.hxx"
00074 #include "TopTools_DataMapOfShapeInteger.hxx"
00075 //#include "TopOpeBRep_ShapeIntersector.hxx"
00076 //#include "TopOpeBRep_Point2d.hxx"
00077 //#include "TopOpeBRep_EdgesIntersector.hxx"
00078 //#include "TopOpeBRepTool_ShapeTool.hxx"
00079 //#include "BRepPrimAPI_MakePrism.hxx"
00080 // ********** END CUBIT INCLUDES           **********
00081 
00082 // ********** BEGIN FORWARD DECLARATIONS   **********
00083 // ********** END FORWARD DECLARATIONS     **********
00084 
00085 // ********** BEGIN STATIC DECLARATIONS    **********
00086 // ********** END STATIC DECLARATIONS      **********
00087 
00088 // ********** BEGIN PUBLIC FUNCTIONS       **********
00089 
00090 //-------------------------------------------------------------------------
00091 // Purpose       : The default constructor
00092 //
00093 // Special Notes :
00094 //
00095 // Creator:      : Steve Owen
00096 //
00097 // Creation Date : 07/14/00
00098 //-------------------------------------------------------------------------
00099 OCCCurve::OCCCurve( TopoDS_Edge *theEdge )
00100 {
00101   myTopoDSEdge = theEdge;
00102   myMarked = CUBIT_FALSE;
00103   assert (myTopoDSEdge->ShapeType() == TopAbs_EDGE);
00104 }
00105 
00106 //-------------------------------------------------------------------------
00107 // Purpose       : The destructor. 
00108 //
00109 // Special Notes :
00110 //
00111 // Creator       : Steve Owen
00112 //
00113 // Creation Date : 07/14/00
00114 //-------------------------------------------------------------------------
00115 OCCCurve::~OCCCurve() 
00116 {
00117   if (myTopoDSEdge)
00118   {
00119     myTopoDSEdge->Nullify();
00120     delete (TopoDS_Edge *)myTopoDSEdge;
00121     myTopoDSEdge = NULL;
00122   }
00123 }
00124 
00125 //-------------------------------------------------------------------------
00126 // Purpose       : Add and update looplist for the curve, if input loop is 
00127 //                 NULL, just update the looplist.
00128 // Special Notes :
00129 //
00130 // Creator       : Jane Hu
00131 //
00132 // Creation Date : 10/04/12
00133 //-------------------------------------------------------------------------
00134 void OCCCurve::add_loop(OCCLoop* loop) 
00135 { 
00136   //before add the loop into the looplist, check to make sure the 
00137   //looplist is up-to-date
00138   //It should be done somewhere else, however, in large mcnp2cad test, there's
00139   //no way to check where the code forget to remove the out-dated loop.
00140   for (int i = 0; i < myLoopList.size(); i++)
00141   {
00142     OCCLoop* myLoop = CAST_TO(myLoopList.get(), OCCLoop);
00143 
00144     if(!myLoop) 
00145       this->remove_loop(myLoopList.get());
00146     else if(myLoop->get_TopoDS_Wire() < (void*) 0x1000)
00147       this->remove_loop(myLoop);
00148     else if(myLoop->coedges().size() == 0)
00149       this->remove_loop(myLoop);
00150     myLoopList.step();
00151   }
00152   if(loop != NULL)
00153     myLoopList.append_unique(loop);
00154 }
00155 
00156 void OCCCurve::set_TopoDS_Edge(TopoDS_Edge edge)
00157 {
00158   if(myTopoDSEdge && edge.IsEqual(*myTopoDSEdge))
00159     return;
00160 
00161   else
00162   {
00163     DLIList<OCCPoint*> points ;
00164     this->get_points(points);
00165     for(int i = 0; i < points.size(); i++)
00166     {
00167       OCCPoint* point = points.get_and_step();
00168       TopoDS_Vertex* vtx = point->get_TopoDS_Vertex();
00169       TopExp_Explorer Ex;
00170       CubitBoolean found = false;
00171       for (Ex.Init(edge, TopAbs_VERTEX); Ex.More(); Ex.Next())
00172       {
00173         TopoDS_Shape sh = Ex.Current();
00174         if(vtx->IsPartner(sh))
00175         {
00176            found = true;
00177            break;
00178          }
00179       }
00180       if (!found)
00181         point->remove_curve(this);
00182     }
00183   }
00184  
00185   if(myTopoDSEdge)
00186     myTopoDSEdge->Nullify();
00187   *myTopoDSEdge = edge;
00188 }
00189 
00190 //-------------------------------------------------------------------------
00191 // Purpose       : The purpose of this function is to append a
00192 //                 attribute to the GE. The name is attached to the 
00193 //                 underlying solid model entity this one points to.
00194 //
00195 //
00196 // Special Notes : 
00197 //
00198 // Creator       : Steve Owen
00199 //
00200 // Creation Date : 07/14/00
00201 //-------------------------------------------------------------------------
00202 void OCCCurve::append_simple_attribute_virt(const CubitSimpleAttrib &csa)
00203   { OCCAttribSet::append_attribute(csa, *myTopoDSEdge); }
00204 
00205 //-------------------------------------------------------------------------
00206 // Purpose       : The purpose of this function is to remove a simple 
00207 //                 attribute attached to this geometry entity. The name is 
00208 //                 removed from the underlying BODY this points to.
00209 //
00210 // Special Notes : 
00211 //
00212 // Creator       : Steve Owen
00213 //
00214 // Creation Date : 07/14/00
00215 //-------------------------------------------------------------------------
00216 void OCCCurve::remove_simple_attribute_virt(const CubitSimpleAttrib& csa)
00217   { OCCAttribSet::remove_attribute(csa, *myTopoDSEdge); }
00218 
00219 //-------------------------------------------------------------------------
00220 // Purpose       : The purpose of this function is to remove all simple 
00221 //                 attributes attached to this geometry entity.  Also
00222 //                 removes lingering GTC attributes.
00223 //
00224 //
00225 // Special Notes : 
00226 //
00227 // Creator       : Steve Owen
00228 //
00229 // Creation Date : 07/14/00
00230 //-------------------------------------------------------------------------
00231 void OCCCurve::remove_all_simple_attribute_virt()
00232 {
00233   OCCAttribSet::remove_attribute(CubitSimpleAttrib(), *myTopoDSEdge);
00234 }
00235 
00236 //-------------------------------------------------------------------------
00237 // Purpose       : The purpose of this function is to get the  
00238 //                 attributes attached to this geometry entity. The name is 
00239 //                 attached to the underlying BODY this points to.
00240 //
00241 // Special Notes : 
00242 //
00243 // Creator       : Steve Owen
00244 //
00245 // Creation Date : 07/14/00
00246 //-------------------------------------------------------------------------
00247 CubitStatus OCCCurve::get_simple_attribute(DLIList<CubitSimpleAttrib>&
00248                                                csa_list)
00249   { return OCCAttribSet::get_attributes(*myTopoDSEdge, csa_list); }
00250   
00251 CubitStatus OCCCurve::get_simple_attribute( const CubitString& name,
00252                                       DLIList<CubitSimpleAttrib>& csa_list)
00253   { return OCCAttribSet::get_attributes( name, *myTopoDSEdge, csa_list ); }
00254 
00255 //-------------------------------------------------------------------------
00256 // Purpose       : Get geometry modeling engine: OCCQueryEngine
00257 //
00258 // Special Notes :
00259 //
00260 // Creator       : Steve Owen
00261 //
00262 // Creation Date : 07/14/00
00263 //-------------------------------------------------------------------------
00264 GeometryQueryEngine* OCCCurve::get_geometry_query_engine() const
00265 {
00266   return OCCQueryEngine::instance();
00267 }                 
00268 
00269 //-------------------------------------------------------------------------
00270 // Purpose       : Get the bounding box of the object.
00271 //
00272 // Special Notes :
00273 //
00274 // Creator       : Steve Owen
00275 //
00276 // Creation Date : 10/23/96
00277 //-------------------------------------------------------------------------
00278 CubitBox OCCCurve::bounding_box() const 
00279 {
00280   BRepAdaptor_Curve acurve(*myTopoDSEdge);
00281   Bnd_Box aBox;
00282   BndLib_Add3dCurve::Add(acurve, Precision::Approximation(), aBox);
00283   double min[3], max[3];
00284   aBox.Get( min[0], min[1], min[2], max[0], max[1], max[2]);
00285   return CubitBox(min, max);
00286 }
00287 
00288 
00289 //-------------------------------------------------------------------------
00290 // Purpose       : Return the length of the curve.
00291 //
00292 // Special Notes :
00293 //
00294 // Creator       : Steve Owen
00295 //
00296 // Creation Date : 07/14/00
00297 //-------------------------------------------------------------------------
00298 double OCCCurve::measure()
00299 {
00300   GProp_GProps myProps;
00301   BRepGProp::LinearProperties(*myTopoDSEdge, myProps);
00302   return myProps.Mass();
00303 }
00304 
00305 //-------------------------------------------------------------------------
00306 // Purpose       : Return the arc length along the Curve starting from
00307 //                 the point represented by the parameter1 going to the 
00308 //                 point represented by parameter2.
00309 //
00310 // Special Notes : The sign of the returned length value is always positive.
00311 //                 Parameter1 and parameter2 are with respect to the EDGE.
00312 //
00313 // Creator       : Steve Owen
00314 //
00315 // Creation Date : 07/14/00
00316 //-------------------------------------------------------------------------
00317 double OCCCurve::length_from_u( double parameter1, double parameter2 )
00318 {
00319   BRepAdaptor_Curve acurve(*myTopoDSEdge);
00320   return GCPnts_AbscissaPoint::Length(acurve, parameter1, parameter2);
00321 }
00322 
00323 //-------------------------------------------------------------------------
00324 // Purpose       : Returns CUBIT_TRUE and the associated period value. Not
00325 //                 implemented yet
00326 //
00327 // Special Notes :  
00328 //
00329 // Creator       : Steve Owen
00330 //
00331 // Creation Date : 07/14/00
00332 //-------------------------------------------------------------------------
00333 CubitBoolean OCCCurve::is_periodic(double& period)
00334 {
00335   BRepAdaptor_Curve acurve(*myTopoDSEdge);
00336   if (acurve.IsPeriodic())
00337   {
00338     period = acurve.Period();
00339     return CUBIT_TRUE;
00340   }
00341   return CUBIT_FALSE;
00342 }
00343 
00344 //------------------------------------------------------------------
00345 // Purpose: Returns CUBIT_TRUE and the associated parametric values, 
00346 //          if the facet curve associated with the first EDGE is 
00347 //          parametric.
00348 //          Otherwise returns CUBIT_FALSE and the values of 
00349 //          the lower and upper parametric bounds are undetermined.
00350 //          NOT IMPLEMENTED YET
00351 //
00352 // Creator       : Steve Owen
00353 //
00354 // Creation Date : 07/14/00
00355 //-------------------------------------------------------------------
00356 CubitBoolean OCCCurve::get_param_range( double& lower_bound,
00357                                         double& upper_bound )
00358 {
00359   BRepAdaptor_Curve acurve(*myTopoDSEdge);
00360   lower_bound = acurve.FirstParameter();
00361   upper_bound = acurve.LastParameter();
00362   return CUBIT_TRUE;
00363 }
00364 
00365 
00366 //------------------------------------------------------------------
00367 // Purpose:        Finds the extrema along this Curve. 
00368 //
00369 // Special Notes : It is the responsibility of the
00370 //                 calling code to delete the CubitVectors added to 
00371 //                 interior_points!
00372 //
00373 // Creator       : Jason Kraftcheck
00374 //
00375 // Creation Date : 05/29/01
00376 //-------------------------------------------------------------------
00377 CubitStatus OCCCurve::get_interior_extrema(
00378   DLIList<CubitVector*>& interior_points,
00379   CubitSense& return_sense )
00380 {
00381   DLIList<CubitVector*> point_list;
00382   CubitVector x(1.0, 0.0, 0.0);
00383   get_interior_extrema_in_direction(point_list, x);
00384   CubitVector y(0.0, 1.0, 0.0);
00385   get_interior_extrema_in_direction(point_list, y);
00386   CubitVector z(0.0, 0.0, 1.0);
00387   get_interior_extrema_in_direction(point_list, z );
00388 
00389   //like , return only points that aren't at an endpoint and are not
00390   //close to previous point
00391   const double epsilon = 30.* GEOMETRY_RESABS;
00392   const double epsilon_squared = epsilon*epsilon;
00393 
00394   //get both vertices' coordinates.
00395   CubitVector endpoints[2];
00396   int i = 0;
00397   TopExp_Explorer aVertexExp(*myTopoDSEdge, TopAbs_VERTEX);
00398   while(aVertexExp.More())
00399   {
00400      TopoDS_Vertex v = TopoDS::Vertex(aVertexExp.Current());
00401      gp_Pnt p = BRep_Tool::Pnt(v);
00402      endpoints[i].x(p.X());
00403      endpoints[i].y(p.Y());
00404      endpoints[i].z(p.Z());  
00405      i++;
00406      aVertexExp.Next();
00407   } 
00408 
00409   //compare to see if the Points in point_list are interior and far apart
00410   int j;
00411   CubitVector* cubit_position = NULL;
00412   CubitVector * temp_position = NULL;
00413   point_list.sort();
00414   point_list.reset();
00415   for (j = point_list.size(); j--; )
00416   {
00417      temp_position = point_list.get_and_step();
00418      // save if not equal to an endpoint, or prior point
00419      if (temp_position->distance_between_squared(endpoints[0]) > epsilon_squared
00420         &&
00421         temp_position->distance_between_squared(endpoints[1]) > epsilon_squared)
00422      {
00423         if (!cubit_position ||
00424             temp_position->distance_between_squared(*cubit_position) > epsilon_squared)
00425         {
00426           cubit_position = temp_position ;
00427           interior_points.append( cubit_position );
00428         } // If point isn't close to previous point
00429      } // If point isn't at an endpoint
00430   } // for each point
00431 
00432   // Return sense is whatever the sense of this curve is.
00433   TopAbs_Orientation sense = myTopoDSEdge->Orientation();
00434   return_sense = (sense == TopAbs_FORWARD ? CUBIT_FORWARD : CUBIT_REVERSED);
00435  
00436   return CUBIT_SUCCESS;
00437 }
00438 
00439 CubitStatus OCCCurve::get_interior_extrema_in_direction(
00440             DLIList<CubitVector*>& interior_points,
00441             CubitVector dir)
00442 {
00443   //Create a straight line.
00444   gp_Pnt origin(0.0, 0.0, 0.0);
00445   gp_Dir adir(dir.x(), dir.y(), dir.z());
00446   Handle(Geom_Line) line = GC_MakeLine(origin, adir);
00447 
00448   //get the Geom_Curve of the OCCCurve
00449   Standard_Real first;
00450   Standard_Real last;
00451   Handle(Geom_Curve) myCurve = BRep_Tool::Curve(*myTopoDSEdge, first, last);
00452   
00453   GeomAPI_ExtremaCurveCurve extrema(myCurve, line);
00454   int nPnt = extrema.NbExtrema();
00455   for (int i = 1; i <= nPnt ; i++)
00456   {
00457     gp_Pnt P1, P2;
00458     extrema.Points(i, P1, P2);
00459     CubitVector* v = new CubitVector(P1.X(), P1.Y(), P1.Z());
00460     interior_points.append(v);
00461   }
00462   return CUBIT_SUCCESS;
00463 }  
00464 //-------------------------------------------------------------------------
00465 // Purpose       : This function computes the point on the curve closest 
00466 //                 to the input location.  Optionally, it can also compute
00467 //                 the tangent and curvature on the Curve at the point on
00468 //                 on the Curve closest to the input location.
00469 //
00470 // Special Notes : The tangent direction is always in the positive direction of the 
00471 //                 owning RefEdge, regardless of the positive direction of the
00472 //                 underlying solid model entities.
00473 //
00474 //                 If the calling code needs the tangent and/or the curvature,
00475 //                 it is responsible for allocating the memory for these
00476 //                 CubitVector(s) and sending in the relevant non-NULL
00477 //                 pointers to this routine.
00478 //
00479 // Creator       : Steve Owen
00480 //
00481 // Creation Date : 07/14/00
00482 //-------------------------------------------------------------------------
00483 CubitStatus OCCCurve::closest_point( 
00484   CubitVector const& location, 
00485   CubitVector& closest_location,
00486   CubitVector* tangent_ptr,
00487   CubitVector* curvature_ptr,
00488   double* param)
00489 {  
00490   BRepAdaptor_Curve acurve(*myTopoDSEdge);
00491   gp_Pnt p(location.x(), location.y(), location.z()), newP(0.0, 0.0, 0.0);
00492   Extrema_ExtPC ext(p, acurve, Precision::Approximation());
00493   if (!ext.IsDone())
00494     return CUBIT_FAILURE;
00495 
00496   double sqr_dist = CUBIT_DBL_MAX;
00497   double pparam = 0.0;
00498   for (int i = 1; i <= ext.NbExt(); ++i) {
00499       double new_sqr_dist = p.SquareDistance( ext.Point(i).Value() );
00500       if (new_sqr_dist < sqr_dist) {
00501         sqr_dist = new_sqr_dist;
00502         newP = ext.Point(i).Value();
00503         pparam = ext.Point(i).Parameter();
00504       }
00505   }
00506 
00507     // if we didn't find any minimum...
00508   if (sqr_dist == CUBIT_DBL_MAX)
00509     return CUBIT_FAILURE;
00510 
00511     // pass back closest point
00512   closest_location.set( newP.X(), newP.Y(), newP.Z() );
00513   if (param != NULL)
00514     *param = pparam;
00515 
00516     // pass back tangent
00517   if (tangent_ptr != NULL) {
00518     BRepLProp_CLProps CLP(acurve, 2, Precision::PConfusion());
00519     CLP.SetParameter( pparam );
00520     if (!CLP.IsTangentDefined())
00521       return CUBIT_FAILURE;
00522 
00523     gp_Dir tangent;
00524     CLP.Tangent(tangent);
00525     tangent_ptr->set( tangent.X(), tangent.Y(), tangent.Z() );
00526   }
00527 
00528     // if requested, pass back curvature
00529   if (curvature_ptr != NULL)
00530     get_curvature( closest_location, *curvature_ptr );
00531 
00532   return CUBIT_SUCCESS;
00533 }
00534 
00535 
00536 //------------------------------------------------------------------
00537 // Purpose: This function returns the coordinate of a point in the local
00538 //          parametric (u) space that corresponds to the input position 
00539 //          in global (world) space.  The input point is first moved to 
00540 //          the closest point on the Curve and the parameter value of 
00541 //          that point is determined. 
00542 //
00543 // Creator       : Steve Owen
00544 //
00545 // Creation Date : 07/14/00
00546 //-------------------------------------------------------------------
00547 CubitStatus OCCCurve::position_from_u (double u_value,
00548                                         CubitVector& output_position)
00549 {
00550   BRepAdaptor_Curve acurve(*myTopoDSEdge);
00551   gp_Pnt p = acurve.Value(u_value);
00552   output_position.x(p.X());
00553   output_position.y(p.Y());
00554   output_position.z(p.Z());
00555   return CUBIT_SUCCESS;
00556 }
00557 
00558 //-------------------------------------------------------------------------
00559 // Purpose       : This function returns the coordinate of a point in the local
00560 //                 parametric (u) space that corresponds to the input position 
00561 //                 in global (world) space.  The input point is first moved to 
00562 //                 the closest point on the Curve and the parameter value of 
00563 //                 that point is determined. 
00564 //
00565 // Special Notes : 
00566 //
00567 // Creator       : Malcolm J. Panthaki
00568 //
00569 // Creation Date : 2/25/97
00570 //-------------------------------------------------------------------------
00571 double OCCCurve::u_from_position (const CubitVector& input_position)
00572 {
00573     // Get the closest point on the Curve to the input position
00574   CubitVector closest_point;
00575   double u_val;
00576   this->closest_point(input_position, closest_point,
00577                       NULL, NULL, &u_val);
00578     // closest_point already makes adjustments for sense and periodicity
00579   
00580   return u_val;
00581 }
00582 
00583 //------------------------------------------------------------------
00584 // Purpose: This function returns the parameter value of the point 
00585 //          that is "arc_length" away from the root point, in the
00586 //          positive sense direction of the owning RefEdge.
00587 //
00588 // Special Notes : 
00589 //   If arc_length is negative, the new point (whose parameter value
00590 //   is being computed) is in the negative sense direction (along
00591 //   the RefEdge) from the root point (whose parameter value is
00592 //   root_param).
00593 //
00594 //   If the curve is not periodic and the new point, "arc_length"
00595 //   away from the root point in the appropriate direction, goes
00596 //   beyond the end point of the first EDGE, that end point is used
00597 //   to generate the returned parameter value.
00598 //
00599 // If the curve is periodic and the new point, "arc_length" away
00600 // from the root point in the appropriate direction, goes beyond
00601 // the end point of the first EDGE, wrap around is done.  After
00602 // wrap around, the point is treated as with other curves
00603 //
00604 // NOTE:
00605 // The important assumption that is made in this routine is that
00606 // the end points of the RefEdge that owns this Curve are the
00607 // same as the end points of the first  EDGE in the list of EDGEs
00608 // associated with this Curve.
00609 //
00610 // Assume that the parameter root_param is with respect to the
00611 // RefEdge as well as arc_length.  Before calling the  "curve",
00612 // we need to get them with respect to the curve.   
00613 //
00614 // Creator       : Malcolm J. Panthaki
00615 //
00616 // Creation Date : 2/28/97
00617 //------------------------------------------------------------------
00618 double OCCCurve::u_from_arc_length ( double root_param,
00619                                        double arc_length )
00620 {
00621   BRepAdaptor_Curve acurve(*myTopoDSEdge);
00622   GCPnts_AbscissaPoint abs(acurve, arc_length, root_param);
00623   if (abs.IsDone()) return abs.Parameter();
00624   else return 0.0;
00625 }
00626 
00627 //-------------------------------------------------------------------------
00628 // Purpose       : This function tests the passed in position to see if
00629 //                 is on the underlying curve. 
00630 //
00631 // Special Notes :
00632 //
00633 // Creator       : Steve Owen
00634 //
00635 // Creation Date : 07/14/00
00636 //-------------------------------------------------------------------------
00637 CubitBoolean OCCCurve::is_position_on( const CubitVector &test_position )
00638 {
00639   CubitVector new_point;
00640   CubitStatus stat = closest_point(test_position, new_point, NULL,NULL,NULL);
00641 
00642   if ( !stat )
00643     return CUBIT_FALSE;
00644   CubitVector result_vec = test_position - new_point;
00645   if ( result_vec.length_squared() < GEOMETRY_RESABS )
00646     return CUBIT_TRUE;
00647   return CUBIT_FALSE;
00648 }
00649 
00650 //-------------------------------------------------------------------------
00651 // Purpose       : This function returns the type of underlying curve. 
00652 //
00653 // Special Notes : It checks to see if *any* of the  curves associated
00654 //                 with the EDGEs in the list of EDGEs of this Curve is of
00655 //                 a particular type and returns the appropriate value
00656 //                 of the enum, CurveType.
00657 //
00658 // Creator       : Steve Owen
00659 //
00660 // Creation Date : 07/14/00
00661 //-------------------------------------------------------------------------
00662 GeometryType OCCCurve::geometry_type()
00663 {
00664   BRepAdaptor_Curve acurve(*myTopoDSEdge);
00665   if (acurve.GetType() == GeomAbs_BezierCurve)
00666      return SPLINE_CURVE_TYPE;
00667   if (acurve.GetType() == GeomAbs_BSplineCurve)
00668      return SPLINE_CURVE_TYPE;
00669   if (acurve.GetType() == GeomAbs_Line)
00670      return STRAIGHT_CURVE_TYPE;
00671   if (acurve.GetType() == GeomAbs_Parabola)
00672      return PARABOLA_CURVE_TYPE;
00673   if (acurve.GetType() == GeomAbs_Hyperbola)
00674      return HYPERBOLA_CURVE_TYPE;
00675   if (acurve.GetType() == GeomAbs_Circle)
00676       return ARC_CURVE_TYPE;
00677   if (acurve.GetType() == GeomAbs_Ellipse)
00678      return ELLIPSE_CURVE_TYPE;
00679   return UNDEFINED_CURVE_TYPE;
00680 }
00681 
00682 //-------------------------------------------------------------------------
00683 // Purpose       : Return direction of point on curve
00684 //
00685 // Special Notes : Finds the underlying line's origin and direction unit vector
00686 //
00687 // Creator       : Jane Hu
00688 //
00689 // Creation Date : 11/14/07
00690 //-------------------------------------------------------------------------
00691 CubitStatus OCCCurve::get_point_direction( CubitVector& point, 
00692                                            CubitVector& direction )
00693 {
00694   if (geometry_type() != STRAIGHT_CURVE_TYPE)
00695     return CUBIT_FAILURE;
00696 
00697   //get the underlying geometry curve
00698   double first,last;
00699   Handle(Geom_Curve) gCurve = BRep_Tool::Curve(*myTopoDSEdge, first, last);
00700 
00701   //get the origin and direction of the underlying curve
00702   Handle(Geom_Line) gLine = Handle(Geom_Line)::DownCast(gCurve);
00703   gp_Ax1 axis = gLine->Position();
00704   gp_Pnt loc = axis.Location();
00705   gp_Dir dir = axis.Direction();
00706   point.set(loc.X(), loc.Y(), loc.Z());
00707 
00708   //Based on the TopoDS_Edge's orientation, give the unit vector.
00709   if (myTopoDSEdge->Orientation() == TopAbs_FORWARD)
00710     direction.set(dir.X(), dir.Y(), dir.Z());
00711   else if(myTopoDSEdge->Orientation() == TopAbs_REVERSED)
00712     direction.set(-dir.X(), -dir.Y(), -dir.Z());
00713   return CUBIT_SUCCESS;  
00714 }
00715 
00716 //-------------------------------------------------------------------------
00717 // Purpose       : Return the center and radius of an arc
00718 //
00719 // Special Notes : not currently implemented
00720 //
00721 // Creator       : Steve Owen
00722 //
00723 // Creation Date : 07/14/00
00724 //-------------------------------------------------------------------------
00725 CubitStatus OCCCurve::get_center_radius( CubitVector& center, 
00726                                            double& radius )
00727 {
00728   if( geometry_type() != ELLIPSE_CURVE_TYPE &&
00729       geometry_type() != ARC_CURVE_TYPE )
00730     return CUBIT_FAILURE;
00731  
00732   //get the Geom_Curve of the OCCCurve
00733   Standard_Real first;
00734   Standard_Real last;
00735   Handle(Geom_Curve) myCurve = BRep_Tool::Curve(*myTopoDSEdge, first, last); 
00736 
00737   if (Handle(Geom_Circle) gCircle = Handle(Geom_Circle)::DownCast(myCurve))
00738   {
00739      radius = gCircle->Radius();
00740      gp_Circ gp_circ = gCircle->Circ();
00741      gp_Pnt  gp_p = gp_circ.Location();
00742      center.set(gp_p.X(), gp_p.Y(), gp_p.Z());
00743   }
00744 
00745   else //ellipse
00746   {
00747      Handle(Geom_Ellipse) gEllipse = Handle(Geom_Ellipse)::DownCast(myCurve);
00748      radius = gEllipse->MajorRadius();
00749      gp_Elips gp_ellip = gEllipse->Elips();
00750      gp_Pnt  gp_p = gp_ellip.Location();
00751      center.set(gp_p.X(), gp_p.Y(), gp_p.Z());
00752   }
00753   return CUBIT_SUCCESS;
00754 }
00755 
00756 //-------------------------------------------------------------------------
00757 // Purpose       : This function returns the start parameter.
00758 //
00759 // Special Notes : The start param is with respect to the ref_edge.
00760 //
00761 // Creator       : Steve Owen
00762 //
00763 // Creation Date : 07/14/00
00764 //-------------------------------------------------------------------------
00765 double OCCCurve::start_param()
00766 {
00767    double start = 0.0, end = 0.0;
00768    get_param_range( start, end );
00769    return start;
00770 }
00771 
00772 //-------------------------------------------------------------------------
00773 // Purpose       : This function returns the end parameter.
00774 //
00775 // Special Notes : The end param is with respect to the ref_edge.
00776 //
00777 // Creator       : Steve Owen
00778 //
00779 // Creation Date : 07/14/00
00780 //-------------------------------------------------------------------------
00781 double OCCCurve::end_param()
00782 {
00783    double start = 0.0, end = 0.0;
00784    
00785    get_param_range( start, end );
00786    return end;
00787 }
00788 
00789 
00790 void OCCCurve::get_parents_virt( DLIList<TopologyBridge*>& parents ) 
00791 { 
00792    //check to see all myLoops are up-to-date.
00793    add_loop(NULL);
00794 
00795    for(int i = 0; i < myLoopList.size(); i++) 
00796    {
00797       DLIList<OCCCoEdge*> coedges = myLoopList.get_and_step()->coedges();
00798     
00799       for(int j = 0; j < coedges.size(); j++)
00800       {
00801         OCCCoEdge * coedge = coedges.get_and_step();
00802     if(coedge->curve() == this)
00803     {
00804       parents.append(coedge);
00805           break;
00806     }
00807       }
00808    }
00809 }
00810 void OCCCurve::get_children_virt( DLIList<TopologyBridge*>& children ) 
00811 {
00812     TopTools_IndexedMapOfShape M;
00813     TopExp::MapShapes(*myTopoDSEdge, TopAbs_VERTEX, M);
00814         int ii ;
00815         for (ii = M.Extent();  ii > 0; ii--) {
00816              TopologyBridge *point = OCCQueryEngine::instance()->occ_to_cgm(M(ii));
00817               if (point)
00818                 children.append_unique(point);
00819        }
00820        if(children.size() ==0)
00821          return;
00822        //make sure the points are in the start-end order
00823        double start , end;     
00824        get_param_range( start, end );
00825        CubitVector v;
00826        position_from_u(start, v);
00827        children.reset();
00828        if(!v.about_equal(CAST_TO(children.get(), TBPoint)->coordinates())) 
00829          children.reverse();
00830 }
00831  
00832 
00833 
00834 
00835 //-------------------------------------------------------------------------
00836 // Purpose       : Check for G1 discontinuity
00837 //
00838 // Special Notes : returns tangency discontinuity all along the Curve
00839 //         at the param, only returns minus tangent = plus tangent
00840 //         when it's C1 continuity.
00841 //
00842 // Creator       : Jane Hu
00843 //
00844 // Creation Date : 11/14/07
00845 //-------------------------------------------------------------------------
00846 CubitBoolean OCCCurve::G1_discontinuous( 
00847       double param, CubitVector* mtan, CubitVector* ptan )
00848 { 
00849   CubitBoolean is_discon = CUBIT_TRUE;
00850   double first, last;
00851   Handle(Geom_Curve) gCurve = BRep_Tool::Curve(*myTopoDSEdge, first, last);
00852 
00853   if (gCurve->Continuity() < GeomAbs_G1)
00854      return is_discon;
00855 
00856   assert(first <= param && param <= last );
00857   
00858   gp_Pnt P;
00859   gp_Vec V1;
00860   gCurve->D1(param, P, V1);
00861   
00862   mtan = new CubitVector(V1.X(), V1.Y(),V1.Z());
00863   ptan = new CubitVector(*mtan);
00864      
00865   return CUBIT_FALSE;
00866 }
00867 
00868 void OCCCurve::get_points( DLIList<OCCPoint*>& result_list )
00869 {
00870   TopTools_IndexedMapOfShape M;
00871   TopExp::MapShapes(*myTopoDSEdge, TopAbs_VERTEX, M);
00872   int ii;
00873   for (ii=M.Extent(); ii>0; ii--) {
00874       TopologyBridge *point = OCCQueryEngine::instance()->occ_to_cgm(M(ii));
00875           if (point)
00876         result_list.append_unique(dynamic_cast<OCCPoint*>(point));
00877   }
00878   if(result_list.size() ==0)
00879     return;
00880   //make sure the points are in the start-end order
00881   double start , end;     
00882   get_param_range( start, end );
00883   CubitVector v;
00884   position_from_u(start, v);
00885   result_list.reset();
00886   if(!v.about_equal(result_list.get()->coordinates()))
00887     result_list.reverse();
00888 
00889 }
00890 
00891 void OCCCurve::get_tangent( CubitVector const& location,
00892                             CubitVector& tangent)
00893 {
00894     double u = u_from_position(location);
00895     Standard_Real first;
00896     Standard_Real last;
00897     Handle(Geom_Curve) myCurve = BRep_Tool::Curve(*myTopoDSEdge, first, last);
00898  
00899     gp_Pnt p;
00900     gp_Vec tan;
00901     GeomLProp_CurveTool::D1(myCurve, u , p, tan) ;
00902     tangent.set(tan.X(), tan.Y(), tan.Z());
00903 } 
00904 
00905 void OCCCurve::get_curvature( CubitVector const& location,
00906                               CubitVector& curvature)
00907 {  
00908     double u = u_from_position(location);
00909     Standard_Real first;
00910     Standard_Real last;
00911     Handle(Geom_Curve) myCurve = BRep_Tool::Curve(*myTopoDSEdge, first, last);
00912 
00913     gp_Pnt p;
00914     gp_Vec tan, cur;
00915     GeomLProp_CurveTool::D2(myCurve, u , p, tan, cur) ;
00916     curvature.set(cur.X(), cur.Y(), cur.Z()); 
00917 }
00918 
00919 // ********** END PUBLIC FUNCTIONS         **********
00920 
00921 // ********** BEGIN PROTECTED FUNCTIONS    **********
00922 // ********** END PROTECTED FUNCTIONS      **********
00923 
00924 // ********** BEGIN PRIVATE FUNCTIONS      **********
00925 
00926 
00927 //----------------------------------------------------------------
00928 // Adjusts the input parameter so that it falls within the
00929 // parameter range of this Curve, if possible.  Necessary for
00930 // periodic curves.
00931 //----------------------------------------------------------------
00932 void OCCCurve::adjust_periodic_parameter(double& param)
00933 {
00934     // Adjustment only legal if this is a periodic curve.
00935   double period;
00936   if ( this->is_periodic(period) && (fabs(period) > CUBIT_RESABS))
00937   {
00938     double upper_bound, lower_bound;
00939     this->get_param_range( lower_bound, upper_bound );
00940     assert((upper_bound - lower_bound) > CUBIT_RESABS * 100);
00941 
00942     lower_bound -= CUBIT_RESABS;
00943     upper_bound += CUBIT_RESABS;
00944     
00945       // Make sure period is positive
00946     if (period < 0.)
00947       period = -period;
00948 
00949       // Move the parameter above the low param
00950     while (param < lower_bound)
00951       param += period;
00952       // Move the parameter below the high param
00953     while (param > upper_bound)
00954       param -= period;
00955   }
00956 }
00957 
00958 //-------------------------------------------------------------------------
00959 // Purpose       : Return the spline parameters given a curve that is a spline
00960 //
00961 // Special Notes :
00962 //
00963 // Creator       : Jane Hu
00964 //
00965 // Creation Date : 2/20/2012
00966 //-------------------------------------------------------------------------
00967 CubitStatus OCCCurve::get_spline_params
00968 (
00969   bool &rational,    // return true/false
00970   int &degree,       // the degree of this spline
00971   DLIList<CubitVector> &cntrl_pts,  // xyz position of controlpoints
00972   DLIList<double> &cntrl_pt_weights, // if rational, a weight for each cntrl point.
00973   DLIList<double> &knots   // There should be order+cntrl_pts.size()-2 knots
00974 ) const
00975 {
00976   BRepAdaptor_Curve acurve(*myTopoDSEdge);
00977   Handle_Geom_BSplineCurve h_S = NULL;
00978   if (acurve.GetType() == GeomAbs_BSplineCurve)
00979     h_S = acurve.BSpline();
00980   else
00981     return CUBIT_FAILURE;
00982   assert ( h_S != NULL);
00983 
00984   rational = h_S->IsRational();
00985   degree =   h_S->Degree();
00986   
00987   TColStd_Array1OfReal K(1, h_S->NbKnots());
00988   h_S->Knots(K);
00989   for (int i = K.Lower(); i <= K.Upper(); i++)
00990     knots.append(K.Value(i));
00991 
00992   TColgp_Array1OfPnt P(1, h_S->NbPoles());
00993   h_S->Poles(P);
00994   for (int i = P.Lower(); i <= P.Upper(); i++) 
00995   {
00996     gp_Pnt point = P.Value(i);
00997     CubitVector v = CubitVector(point.X(), point.Y(), point.Z());
00998     cntrl_pts.append(v); 
00999   }
01000 
01001   if(rational)
01002   {
01003     TColStd_Array1OfReal W(1, h_S->NbPoles());
01004     h_S->Weights(W);
01005     for (int i = W.Lower(); i <= W.Upper(); i++)
01006       cntrl_pt_weights.append(W.Value(i));
01007   }
01008   return CUBIT_SUCCESS;
01009 }
01010 
01011 //-------------------------------------------------------------------------
01012 // Purpose       : Return the ellipse parameters given a curve that is an ellipse
01013 //
01014 // Special Notes :
01015 //
01016 // Creator       : Jane  Hu
01017 //
01018 // Creation Date : 2/21/2012
01019 //-------------------------------------------------------------------------
01020 CubitStatus OCCCurve::get_ellipse_params
01021 (
01022   CubitVector &center_pt,
01023   CubitVector &normal,
01024   CubitVector &major_axis,
01025   double &radius_ratio
01026 ) const
01027 {
01028   BRepAdaptor_Curve acurve(*myTopoDSEdge);
01029   gp_Elips ellipse;
01030   if (acurve.GetType() == GeomAbs_Ellipse)
01031     ellipse = acurve.Ellipse();
01032   else
01033     return CUBIT_FAILURE;
01034 
01035   gp_Pnt center = ellipse.Location();
01036   center_pt = CubitVector(center.X(), center.Y(), center.Z());
01037   
01038   gp_Ax1 normal_Axis = ellipse.Axis();
01039   gp_Dir normal_dir = normal_Axis.Direction();
01040   normal = CubitVector(normal_dir.X(), normal_dir.Y(), normal_dir.Z());
01041 
01042   gp_Ax1 major_Axis = ellipse.Directrix1();
01043   gp_Dir major_dir = major_Axis.Direction();
01044   major_axis = CubitVector(major_dir.X(), major_dir.Y(), major_dir.Z());
01045 
01046   double major = ellipse.MajorRadius();
01047   double minor = ellipse.MinorRadius();
01048   radius_ratio = major/minor;
01049 
01050   return CUBIT_SUCCESS;
01051 }
01052 
01053 CubitPointContainment OCCCurve::point_containment( const CubitVector &point )
01054 {
01055    if (is_position_on(point) == CUBIT_TRUE)
01056    {
01057      DLIList<OCCPoint*> points;
01058      get_points(points);
01059      for (int i = 0; i < points.size(); i++)
01060      {
01061     OCCPoint* pnt = points.get_and_step();
01062         CubitVector v = pnt->coordinates();
01063         double d = v.distance_between(point); 
01064         if (d < GEOMETRY_RESABS)
01065       return CUBIT_PNT_BOUNDARY; 
01066      }
01067      return CUBIT_PNT_ON;
01068    } 
01069    return CUBIT_PNT_OFF;
01070 }
01071 
01072 //----------------------------------------------------------------
01073 // Function: to update the core Curve
01074 //           for any movement of the body/surface/curve.
01075 // Author: Jane Hu
01076 //----------------------------------------------------------------
01077 void OCCCurve::update_OCC_entity( BRepBuilderAPI_ModifyShape *aBRepTrsf,
01078                                  BRepAlgoAPI_BooleanOperation *op)
01079 {
01080   if (myMarked == 1) 
01081      return;
01082 
01083   assert(aBRepTrsf != NULL || op != NULL);
01084   
01085   TopoDS_Shape shape;
01086   if(aBRepTrsf)
01087     shape = aBRepTrsf->ModifiedShape(*get_TopoDS_Edge()); 
01088   else
01089   {
01090     TopTools_ListOfShape shapes;
01091     shapes.Assign(op->Modified(*get_TopoDS_Edge()));
01092     if(shapes.Extent() == 0)
01093       shapes.Assign(op->Generated(*get_TopoDS_Edge()));
01094     if(shapes.Extent() == 1)
01095       shape = shapes.First();
01096     else if(shapes.Extent() > 1)
01097     {
01098       shape = shapes.First();
01099     }
01100     else if (op->IsDeleted(*get_TopoDS_Edge()))
01101       ;
01102     else
01103       return ;
01104   }
01105   TopoDS_Edge curve;
01106   if(!shape.IsNull())
01107     curve = TopoDS::Edge(shape);
01108 
01109   //make sure the shape (edge) length is greater than 0.
01110   GProp_GProps myProps;
01111   BRepGProp::LinearProperties(curve, myProps);
01112   double d = myProps.Mass();
01113   if(d > OCCQueryEngine::instance()->get_sme_resabs_tolerance())
01114   {
01115     //set the vertices
01116     DLIList<TopologyBridge*> vertices;
01117     get_children_virt(vertices);
01118     for (int i = 1; i <= vertices.size(); i++)
01119     {
01120        TopologyBridge* tb = vertices.get_and_step();
01121        OCCPoint *point = CAST_TO(tb, OCCPoint);
01122        if (point)
01123          point->update_OCC_entity(aBRepTrsf, op);
01124     }
01125     myMarked = 1;
01126   }
01127   else
01128     curve.Nullify();
01129   OCCQueryEngine::instance()->update_OCC_map(*myTopoDSEdge, curve);
01130 }
01131 
01132 //===============================================================================
01133 // Function   : project_curve
01134 // Member Type: PUBLIC
01135 // Description: project a curve onto a surface, if closed is true,
01136 //              make sure it projected as two segment, then combine them
01137 //              into a closed shape, third_point is used to determine
01138 //              which segment to use if having two projections.
01139 // Author     : Jane Hu
01140 // Date       : 01/08
01141 //===============================================================================
01142 Curve* OCCCurve::project_curve(Surface* face_ptr, 
01143                                DLIList<TBPoint*>&  normal_proj_points,
01144                                CubitBoolean closed,
01145                                const CubitVector* third_point)
01146 {
01147    TopoDS_Edge* edge = get_TopoDS_Edge();
01148    if (edge == NULL)
01149    {
01150         PRINT_ERROR("Cannot project the curve .\n"
01151                  "Possible incompatible geometry engines.\n");
01152         return (Curve*) NULL;
01153    }
01154 
01155    TopoDS_Face* face = CAST_TO(face_ptr, OCCSurface)->get_TopoDS_Face();
01156    if(face == NULL)
01157    {
01158         PRINT_ERROR("Cannot project the curve to the surface.\n"
01159                  "Possible incompatible geometry engines.\n");
01160         return (Curve*) NULL;
01161    }
01162 
01163    BRepAlgo_NormalProjection aProjection;
01164    aProjection.Init(*face);
01165    aProjection.Add(*edge);
01166    aProjection.Build();
01167    if (!aProjection.IsDone())
01168    {
01169         PRINT_ERROR("Cannot project the curve to the surface.\n"
01170                  "OCC engine failure.\n");
01171         return (Curve*) NULL;
01172    }
01173 
01174    TopoDS_Shape new_shape = aProjection.Projection();//compound shape
01175    int num_projection = 0;
01176    if (new_shape.IsNull())
01177    {
01178        PRINT_ERROR("Cannot project the curve to the surface.\n");
01179        return (Curve*) NULL;
01180    }
01181 
01182    else
01183    {
01184      //count how many free edges and vertices the new_shape has.
01185      TopExp_Explorer Ex;
01186      for (Ex.Init(new_shape,TopAbs_EDGE); Ex.More(); Ex.Next())
01187        num_projection++;
01188      for (Ex.Init(new_shape,TopAbs_VERTEX, TopAbs_EDGE); Ex.More(); Ex.Next())
01189        num_projection++;
01190    }
01191 
01192    if(num_projection == 0)
01193    {
01194       PRINT_INFO("No projection on the surface.\n");
01195       return (Curve*) NULL;
01196    }
01197 
01198    else if ( num_projection == 1 )
01199    {
01200       if(closed == true)
01201        PRINT_WARNING("Cannot project the curve to create a closed projection.\n"                 "There is only one projection segment.\n");
01202 
01203       TopExp_Explorer Ex;
01204       TopoDS_Edge new_edge;
01205       TopoDS_Vertex new_point;
01206       for (Ex.Init(new_shape,TopAbs_EDGE); Ex.More(); Ex.Next())
01207       {
01208         new_edge = TopoDS::Edge(Ex.Current());
01209         return OCCQueryEngine::instance()->populate_topology_bridge(new_edge,
01210                                                                    CUBIT_TRUE );
01211       }
01212       for(Ex.Init(new_shape,TopAbs_VERTEX);Ex.More(); Ex.Next())
01213       {
01214         new_point = TopoDS::Vertex(Ex.Current());
01215         normal_proj_points.append(OCCQueryEngine::instance()->populate_topology_bridge(new_point, CUBIT_TRUE));
01216       } 
01217       return (Curve*) NULL;
01218    }
01219 
01220    else if (num_projection == 2)
01221    {
01222       double d;
01223       double first, last;
01224       TopExp_Explorer Ex;
01225       TopoDS_Edge edge1, edge2;
01226       TopoDS_Vertex point;
01227 
01228       int count = 0;
01229       for (Ex.Init(new_shape,TopAbs_EDGE); Ex.More(); Ex.Next())
01230       {
01231         count++;
01232         if(count == 1)
01233           edge1 = TopoDS::Edge(Ex.Current());
01234         if(count == 2)
01235           edge2 = TopoDS::Edge(Ex.Current());
01236       }
01237 
01238       for(Ex.Init(new_shape,TopAbs_VERTEX);Ex.More(); Ex.Next())
01239       {
01240         point = TopoDS::Vertex(Ex.Current());
01241         normal_proj_points.append(OCCQueryEngine::instance()->populate_topology_bridge(point, CUBIT_TRUE));
01242       }
01243 
01244       if(edge1.IsNull())
01245         return OCCQueryEngine::instance()->populate_topology_bridge(edge2, CUBIT_TRUE);
01246 
01247       if(edge2.IsNull())
01248         return OCCQueryEngine::instance()->populate_topology_bridge(edge1, CUBIT_TRUE);
01249 
01250       if(edge1.IsNull() && edge2.IsNull())
01251         return (Curve*) NULL;
01252 
01253       Handle(Geom_Curve) myCurve1 =
01254                         BRep_Tool::Curve(edge1,first,last);
01255 
01256       Handle(Geom_Curve) myCurve2= BRep_Tool::Curve(edge2, first, last);
01257       //If the surface is periodic, so it has 2 projections, we just need to
01258       //find the segment to which the third_point is closer.
01259       if(closed == CUBIT_FALSE && third_point != NULL)
01260       {
01261         gp_Pnt P (third_point->x(), third_point->y(), third_point->z());
01262         GeomAPI_ProjectPointOnCurve projOncurve(P, myCurve1);
01263         if (projOncurve.NbPoints() == 0)
01264         {
01265           PRINT_ERROR("Cannot project the curve to the surface.\n"
01266                  "OCC engine failure.\n");
01267           return (Curve*) NULL;
01268         }
01269         d = projOncurve.LowerDistance();
01270 
01271         //Compare with the second solution
01272         GeomAPI_ProjectPointOnCurve projOncurve2(P, myCurve2);
01273         if (projOncurve2.NbPoints() == 0)
01274         {
01275            PRINT_ERROR("Cannot project the curve to the surface.\n"
01276                  "OCC engine failure.\n");
01277           return (Curve*) NULL;
01278         }
01279 
01280         double d2 = projOncurve2.LowerDistance();
01281         TopoDS_Edge new_edge =
01282                 d > d2 ? edge2 : edge1 ;
01283         return OCCQueryEngine::instance()->populate_topology_bridge(new_edge, CUBIT_TRUE);
01284       }
01285 
01286 
01287       else if (closed == CUBIT_TRUE)
01288       {
01289         //connect the two segment into a closed shape. Assume both segment
01290         // has the same curve type, create Bezier closed curve.
01291         GeomAdaptor_Curve acurve1(myCurve1);
01292         GeomAdaptor_Curve acurve2(myCurve2);
01293         //get 10 points of each curve, combine them to make one Bezier curve
01294         int NbPoints = 10;
01295         GCPnts_QuasiUniformAbscissa distribution1(acurve1, NbPoints);
01296         GCPnts_QuasiUniformAbscissa distribution2(acurve2, NbPoints);
01297         TColgp_Array1OfPnt points(1, 2*NbPoints-1);
01298         int i;
01299         for (i = 1; i <= NbPoints; i++)
01300         {
01301            double u = distribution1.Parameter(i);
01302            gp_Pnt P = myCurve1->Value(u);
01303            points.SetValue(i, P);
01304         }
01305 
01306         for (int j = NbPoints-1; j >= 1; j--)
01307         {
01308            double u = distribution2.Parameter(j); 
01309            gp_Pnt P = myCurve2->Value(u);
01310            points.SetValue(++i,P); 
01311         }    
01312 
01313         Geom_BezierCurve BezierCurve(points);
01314         Handle(Geom_Curve) curve_ptr(&BezierCurve);
01315         TopoDS_Edge new_edge = BRepBuilderAPI_MakeEdge(curve_ptr);
01316         return OCCQueryEngine::instance()->populate_topology_bridge(new_edge);
01317       }
01318    }
01319    return (Curve*) NULL;
01320 }
01321 CubitStatus OCCCurve::get_spline_params( bool &rational,
01322                                          int &degree,
01323                                          DLIList<CubitVector> &cntrl_pts,
01324                                          DLIList<double> &cntrl_pt_weights,
01325                                          DLIList<double> &knots, // There should be order+cntrl_pts.size()-2 knots
01326                                          bool &spline_is_reversed
01327                                        ) const
01328   {
01329       return CUBIT_FAILURE;
01330   }
01331 
01332 // ********** END PRIVATE FUNCTIONS        **********
01333 
01334 // ********** BEGIN HELPER CLASSES         **********
01335 // ********** END HELPER CLASSES           **********
01336 
01337 // ********** BEGIN EXTERN FUNCTIONS       **********
01338 // ********** END EXTERN FUNCTIONS         **********
01339 
01340 // ********** BEGIN STATIC FUNCTIONS       **********
01341 // ********** END STATIC FUNCTIONS         **********
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines