cgma
|
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 °ree, // 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 ¢er_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 °ree, 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 **********