void VectorFont::Glyph::GlyphLine::glCommands( const gp_Pnt & starting_point, const bool select, const bool marked, const bool no_color, COrientationModifier *pOrientationModifier, gp_Trsf transformation, const float width ) const { gp_Pnt from( starting_point ); gp_Pnt to( starting_point ); from.SetX( starting_point.X() + m_x1); from.SetY( starting_point.Y() + m_y1); from.SetZ( starting_point.Z() ); to.SetX( starting_point.X() + m_x2); to.SetY( starting_point.Y() + m_y2); to.SetZ( starting_point.Z() ); if (pOrientationModifier) { from = pOrientationModifier->Transform(transformation, starting_point.Distance(gp_Pnt(0.0,0.0,0.0)), from, width ); to = pOrientationModifier->Transform(transformation, starting_point.Distance(gp_Pnt(0.0,0.0,0.0)), to, width ); } glBegin(GL_LINE_STRIP); glVertex3d(from.X(), from.Y(), from.Z()); glVertex3d(to.X(), to.Y(), to.Z()); glEnd(); } // End glCommands() method
bool CTiglAbstractGeometricComponent::GetIsOn(const gp_Pnt& pnt) { const TopoDS_Shape& segmentShape = GetLoft()->Shape(); // fast check with bounding box Bnd_Box boundingBox; BRepBndLib::Add(segmentShape, boundingBox); Standard_Real xmin, xmax, ymin, ymax, zmin, zmax; boundingBox.Get(xmin, ymin, zmin, xmax, ymax, zmax); if (pnt.X() < xmin || pnt.X() > xmax || pnt.Y() < ymin || pnt.Y() > ymax || pnt.Z() < zmin || pnt.Z() > zmax) { return false; } double tolerance = 0.03; // 3cm BRepClass3d_SolidClassifier classifier; classifier.Load(segmentShape); classifier.Perform(pnt, tolerance); if ((classifier.State() == TopAbs_IN) || (classifier.State() == TopAbs_ON)) { return true; } else { return false; } }
bool operator()(const gp_Pnt& p1, const gp_Pnt& p2) const { if (fabs(p1.X() - p2.X()) > Precision::Confusion()) return p1.X() < p2.X(); if (fabs(p1.Y() - p2.Y()) > Precision::Confusion()) return p1.Y() < p2.Y(); if (fabs(p1.Z() - p2.Z()) > Precision::Confusion()) return p1.Z() < p2.Z(); return false; // points are considered to be equal }
bool rs274emc::comparePoints(gp_Pnt a,gp_Pnt b) { bool result=0, xIdent=0, yIdent=0, zIdent=0; xIdent=!(a.X()-b.X()); yIdent=!(a.Y()-b.Y()); zIdent=!(a.Z()-b.Z()); if (xIdent && yIdent && zIdent) result=1; return result; }
//is p1 "less than" p2? bool ImpExpDxfWrite::gp_PntCompare(gp_Pnt p1, gp_Pnt p2) { bool result = false; if (!(p1.IsEqual(p2,Precision::Confusion()))) { //ie v1 != v2 if (!(fabs(p1.X() - p2.X()) < Precision::Confusion())) { // x1 != x2 result = p1.X() < p2.X(); } else if (!(fabs(p1.Y() - p2.Y()) < Precision::Confusion())) { // y1 != y2 result = p1.Y() < p2.Y(); } else { result = p1.Z() < p2.Z(); } } return result; }
void CGuideRectODL::SetTopStopPos( gp_Pnt ptStop ) { SetIsTopCreating(false); CBaseODL::SetTopStopPos(ptStop); m_rtArea.Width = static_cast<Gdiplus::REAL>(abs(m_ptTopStart.X() - ptStop.X())); m_rtArea.Height = static_cast<Gdiplus::REAL>(abs(m_ptTopStart.Z() - ptStop.Z())); }
void CGuideRectODL::SetTopCurrentPos( gp_Pnt ptCurrent ) { CBaseODL::SetTopCurrentPos(ptCurrent); m_rtArea.Width = static_cast<Gdiplus::REAL>(abs(m_ptTopStart.X() - ptCurrent.X())); m_rtArea.Height = static_cast<Gdiplus::REAL>(abs(m_ptTopStart.Z() - ptCurrent.Z())); if (m_ptTopStart.X()>ptCurrent.X()) { m_rtArea.X = static_cast<Gdiplus::REAL>(ptCurrent.X()); } if ( ptCurrent.Z()<m_ptTopStart.Z()) { m_rtArea.Y= static_cast<Gdiplus::REAL>(ptCurrent.Z()); } }
void CGuideRectODL::SetTopStartPos( gp_Pnt ptStart ) { SetIsTopCreating(true); CBaseODL::SetTopStartPos(ptStart); m_rtArea.X= static_cast<Gdiplus::REAL>(ptStart.X()); m_rtArea.Y = static_cast<Gdiplus::REAL>(ptStart.Z()); }
std::list<gp_Pnt> VectorFont::Glyph::GlyphArc::Interpolate(const gp_Pnt & location, const unsigned int number_of_points ) const { std::list<gp_Pnt> points; gp_Pnt origin(location); origin.SetX( origin.X() + m_xcentre ); origin.SetY( origin.Y() + m_ycentre ); double start_angle = m_start_angle; double end_angle = m_end_angle; if (start_angle > end_angle) { end_angle += (2 * M_PI); } double increment = (end_angle - start_angle) / number_of_points; gp_Dir z_direction( 0, 0, 1 ); for (double angle = start_angle; angle <= end_angle; angle += increment) { gp_Pnt point( location.X() + m_xcentre + m_radius, location.Y() + m_ycentre, location.Z() ); gp_Trsf rotation_matrix; rotation_matrix.SetRotation( gp_Ax1(origin, z_direction), angle ); point.Transform(rotation_matrix); points.push_back(point); } return(points); }
point3D gPntTopoint3D(gp_Pnt& p) { point3D result; result.x = p.X(); result.y = p.Y(); result.z = p.Z(); return result; }
//!set up a hidden line remover and project a shape with it void GeometryObject::projectShape(const TopoDS_Shape& input, const gp_Pnt& inputCenter, const Base::Vector3d& direction) { // Clear previous Geometry clear(); Base::Vector3d origin(inputCenter.X(),inputCenter.Y(),inputCenter.Z()); gp_Ax2 viewAxis = getViewAxis(origin,direction); auto start = chrono::high_resolution_clock::now(); Handle_HLRBRep_Algo brep_hlr = NULL; try { brep_hlr = new HLRBRep_Algo(); brep_hlr->Add(input, m_isoCount); HLRAlgo_Projector projector( viewAxis ); brep_hlr->Projector(projector); brep_hlr->Update(); brep_hlr->Hide(); } catch (...) { Standard_Failure::Raise("GeometryObject::projectShape - error occurred while projecting shape"); } auto end = chrono::high_resolution_clock::now(); auto diff = end - start; double diffOut = chrono::duration <double, milli> (diff).count(); Base::Console().Log("TIMING - %s GO spent: %.3f millisecs in HLRBRep_Algo & co\n",m_parentName.c_str(),diffOut); try { HLRBRep_HLRToShape hlrToShape(brep_hlr); visHard = hlrToShape.VCompound(); visSmooth = hlrToShape.Rg1LineVCompound(); visSeam = hlrToShape.RgNLineVCompound(); visOutline = hlrToShape.OutLineVCompound(); visIso = hlrToShape.IsoLineVCompound(); hidHard = hlrToShape.HCompound(); hidSmooth = hlrToShape.Rg1LineHCompound(); hidSeam = hlrToShape.RgNLineHCompound(); hidOutline = hlrToShape.OutLineHCompound(); hidIso = hlrToShape.IsoLineHCompound(); //need these 3d curves to prevent "zero edges" later BRepLib::BuildCurves3d(visHard); BRepLib::BuildCurves3d(visSmooth); BRepLib::BuildCurves3d(visSeam); BRepLib::BuildCurves3d(visOutline); BRepLib::BuildCurves3d(visIso); BRepLib::BuildCurves3d(hidHard); BRepLib::BuildCurves3d(hidSmooth); BRepLib::BuildCurves3d(hidSeam); BRepLib::BuildCurves3d(hidOutline); BRepLib::BuildCurves3d(hidIso); } catch (...) { Standard_Failure::Raise("GeometryObject::projectShape - error occurred while extracting edges"); } }
void CSkyODL::OnTopMoving(const gp_Pnt& stInfo) { CBaseODL::OnTopMoving(stInfo); m_arrMovingTopPoint.clear(); //修改所有点的最终位置 for (auto& curPnt : m_arrTopPoint) { gp_Pnt pt(curPnt.X() + stInfo.X(), curPnt.Y() + stInfo.Y(), curPnt.Z() + stInfo.Z() ); m_arrMovingTopPoint.push_back(pt); } }
//======================================================================= //function : FindBestPoint //purpose : Auxilare for Compute() // V - normal to (P1,P2,PC) //======================================================================= static gp_Pnt FindBestPoint(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& PC, const gp_Vec& V) { double a = P1.Distance(P2); double b = P1.Distance(PC); double c = P2.Distance(PC); if( a < (b+c)/2 ) return PC; else { // find shift along V in order to a became equal to (b+c)/2 double shift = sqrt( a*a + (b*b-c*c)*(b*b-c*c)/16/a/a - (b*b+c*c)/2 ); gp_Dir aDir(V); gp_Pnt Pbest( PC.X() + aDir.X()*shift, PC.Y() + aDir.Y()*shift, PC.Z() + aDir.Z()*shift ); return Pbest; } }
/* static */ gp_Pnt HPoint::GetOffset(gp_Pnt location) { wxString message(_("Enter offset in X,Y,Z format (with commas between them)")); wxString caption(_("Apply Offset To Selected Location")); wxString default_value(_T("0,0,0")); wxString value = wxGetTextFromUser(message, caption, default_value); wxStringTokenizer tokens(value,_T(":,\t\n")); for (int i=0; i<3; i++) { if (tokens.HasMoreTokens()) { double offset = 0.0; wxString token = tokens.GetNextToken(); wxString evaluated_version; if (PropertyDouble::EvaluateWithPython( NULL, token, evaluated_version )) { evaluated_version.ToDouble(&offset); offset *= wxGetApp().m_view_units; switch(i) { case 0: location.SetX( location.X() + offset ); break; case 1: location.SetY( location.Y() + offset ); break; case 2: location.SetZ( location.Z() + offset ); break; } } } } return(location); }
//! \relates MathTools gp_Vec operator-(const gp_Pnt& p1, const gp_Pnt& p2) { return gp_Vec(p2.X() - p1.X(), p2.Y() - p1.Y(), p2.Z() - p1.Z()); }
//! project a single face using HLR - used for section faces TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, gp_Pnt faceCenter, const Base::Vector3d &direction) { if(face.IsNull()) { throw Base::Exception("DrawViewSection::projectFace - input Face is NULL"); } Base::Vector3d origin(faceCenter.X(),faceCenter.Y(),faceCenter.Z()); gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(origin,direction); HLRBRep_Algo *brep_hlr = new HLRBRep_Algo(); brep_hlr->Add(face); HLRAlgo_Projector projector( viewAxis ); brep_hlr->Projector(projector); brep_hlr->Update(); brep_hlr->Hide(); HLRBRep_HLRToShape hlrToShape(brep_hlr); TopoDS_Shape hardEdges = hlrToShape.VCompound(); // TopoDS_Shape outEdges = hlrToShape.OutLineVCompound(); std::vector<TopoDS_Edge> faceEdges; TopExp_Explorer expl(hardEdges, TopAbs_EDGE); int i; for (i = 1 ; expl.More(); expl.Next(),i++) { const TopoDS_Edge& edge = TopoDS::Edge(expl.Current()); if (edge.IsNull()) { Base::Console().Log("INFO - DVS::projectFace - hard edge: %d is NULL\n",i); continue; } faceEdges.push_back(edge); } //TODO: verify that outline edges aren't required //if edge is both hard & outline, it will be duplicated? are hard edges enough? // TopExp_Explorer expl2(outEdges, TopAbs_EDGE); // for (i = 1 ; expl2.More(); expl2.Next(),i++) { // const TopoDS_Edge& edge = TopoDS::Edge(expl2.Current()); // if (edge.IsNull()) { // Base::Console().Log("INFO - GO::projectFace - outline edge: %d is NULL\n",i); // continue; // } // bool addEdge = true; // //is edge already in faceEdges? maybe need to use explorer for this for IsSame to work? // for (auto& e:faceEdges) { // if (e.IsPartner(edge)) { // addEdge = false; // Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 1\n"); // } // } // expl.ReInit(); // for (; expl.More(); expl.Next()){ // const TopoDS_Edge& eHard = TopoDS::Edge(expl.Current()); // if (eHard.IsPartner(edge)) { // addEdge = false; // Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 2\n"); // } // } // if (addEdge) { // faceEdges.push_back(edge); // } // } TopoDS_Face projectedFace; if (faceEdges.empty()) { Base::Console().Log("LOG - DVS::projectFace - no faceEdges\n"); return projectedFace; } //recreate the wires for this single face EdgeWalker ew; ew.loadEdges(faceEdges); bool success = ew.perform(); if (success) { std::vector<TopoDS_Wire> fw = ew.getResultNoDups(); if (!fw.empty()) { std::vector<TopoDS_Wire> sortedWires = ew.sortStrip(fw, true); if (sortedWires.empty()) { return projectedFace; } BRepBuilderAPI_MakeFace mkFace(sortedWires.front(),true); //true => only want planes? std::vector<TopoDS_Wire>::iterator itWire = ++sortedWires.begin(); //starting with second face for (; itWire != sortedWires.end(); itWire++) { mkFace.Add(*itWire); } projectedFace = mkFace.Face(); } } else { Base::Console().Warning("DVS::projectFace - input is not planar graph. No face detection\n"); } return projectedFace; }
gp_Pnt MathUtils::projectPointOnPlane(const gp_Pnt &p, const gp_Vec &n) { const gp_Vec pVec(p.X(), p.Y(), p.Z()); const Standard_Real dotVN = pVec.Dot(n); return p.Translated(-dotVN * n); }
//======================================================================= //function : PreciseBoundingBox //purpose : //======================================================================= Standard_Boolean GEOMUtils::PreciseBoundingBox (const TopoDS_Shape &theShape, Bnd_Box &theBox) { if ( theBox.IsVoid() ) BRepBndLib::Add( theShape, theBox ); if ( theBox.IsVoid() ) return Standard_False; Standard_Real aBound[6]; theBox.Get(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]); Standard_Integer i; const gp_Pnt aMid(0.5*(aBound[1] + aBound[0]), // XMid 0.5*(aBound[3] + aBound[2]), // YMid 0.5*(aBound[5] + aBound[4])); // ZMid const gp_XYZ aSize(aBound[1] - aBound[0], // DX aBound[3] - aBound[2], // DY aBound[5] - aBound[4]); // DZ const gp_Pnt aPnt[6] = { gp_Pnt(aBound[0] - (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMin gp_Pnt(aBound[1] + (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMax gp_Pnt(aMid.X(), aBound[2] - (aBound[3] - aBound[2]), aMid.Z()), // YMin gp_Pnt(aMid.X(), aBound[3] + (aBound[3] - aBound[2]), aMid.Z()), // YMax gp_Pnt(aMid.X(), aMid.Y(), aBound[4] - (aBound[5] - aBound[4])), // ZMin gp_Pnt(aMid.X(), aMid.Y(), aBound[5] + (aBound[5] - aBound[4])) // ZMax }; const gp_Dir aDir[3] = { gp::DX(), gp::DY(), gp::DZ() }; const Standard_Real aPlnSize[3] = { 0.5*Max(aSize.Y(), aSize.Z()), // XMin, XMax planes 0.5*Max(aSize.X(), aSize.Z()), // YMin, YMax planes 0.5*Max(aSize.X(), aSize.Y()) // ZMin, ZMax planes }; gp_Pnt aPMin[2]; for (i = 0; i < 6; i++) { const Standard_Integer iHalf = i/2; const gp_Pln aPln(aPnt[i], aDir[iHalf]); BRepBuilderAPI_MakeFace aMkFace(aPln, -aPlnSize[iHalf], aPlnSize[iHalf], -aPlnSize[iHalf], aPlnSize[iHalf]); if (!aMkFace.IsDone()) { return Standard_False; } TopoDS_Shape aFace = aMkFace.Shape(); // Get minimal distance between planar face and shape. Standard_Real aMinDist = GEOMUtils::GetMinDistance(aFace, theShape, aPMin[0], aPMin[1]); if (aMinDist < 0.) { return Standard_False; } aBound[i] = aPMin[1].Coord(iHalf + 1); } // Update Bounding box with the new values. theBox.SetVoid(); theBox.Update(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]); return Standard_True; }
ISession_Text::ISession_Text (const TCollection_AsciiString& aText, gp_Pnt& aPoint, const Aspect_TypeOfText aType, // = SOLID, const Quantity_PlaneAngle anAngle, // = 0.0 const Standard_Real aslant, // = 0.0 const Standard_Integer aColorIndex, // = 0 const Standard_Integer aFontIndex, // = 1 const Quantity_Factor aScale) // = 1 :AIS_InteractiveObject(),MyText(aText),MyX(aPoint.X()),MyY(aPoint.Y()),MyZ(aPoint.Z()), MyTypeOfText(aType),MyAngle(anAngle),MySlant(aslant),MyFontIndex(aFontIndex), MyColorIndex(aColorIndex),MyScale(aScale),MyWidth(0),MyHeight(0) { }
//! \relates MathTools gp_Pnt operator+(const gp_Pnt& p, const gp_Vec& v) { return gp_Pnt(p.X() + v.X(), p.Y() + v.Y(), p.Z() + v.Z()); }
Point::Point(gp_Pnt pnt){ x = pnt.X(); y = pnt.Y(); z = pnt.Z(); }
// static void HDimension::draw_arrow_line(DimensionMode mode, const gp_Pnt &p0, const gp_Pnt &p1, const gp_Pnt &p2, const gp_Dir &xdir, const gp_Dir &ydir, double width, double scale) { double short_line_length = 5.0 * scale; double long_line_extra = 2.0 * scale; double y0 = gp_Vec(p2.XYZ()) * gp_Vec(ydir.XYZ()) - gp_Vec(p0.XYZ()) * gp_Vec(ydir.XYZ()); double y1 = gp_Vec(p2.XYZ()) * gp_Vec(ydir.XYZ()) - gp_Vec(p1.XYZ()) * gp_Vec(ydir.XYZ()); gp_Pnt vt0( p0.XYZ() + ydir.XYZ() * y0); gp_Pnt vt1( p1.XYZ() + ydir.XYZ() * y1); gp_Pnt vt2 = p2; gp_Dir along_dir = make_vector(gp_Pnt(p0), gp_Pnt(p1)); gp_Dir xdir_along = xdir; if(along_dir * xdir < 0)xdir_along = -xdir; gp_Pnt new_vt0 = vt0; gp_Pnt new_vt1 = vt1; gp_Pnt middle_text_point = p2.XYZ() + along_dir.XYZ() * (width/2 * scale); double x0 = gp_Vec(p0.XYZ()) * gp_Vec(xdir_along.XYZ()); double x1 = gp_Vec(p1.XYZ()) * gp_Vec(xdir_along.XYZ()); double xm = gp_Vec(middle_text_point.XYZ()) * gp_Vec(xdir_along.XYZ()); double arrow_head_scale = scale; if(xm < x0 || xm > x1) { arrow_head_scale *= -1; } double distance = vt0.Distance(vt1); // draw arrow heads, if there's room if((distance > 2 * scale + wxGetApp().m_geom_tol) || (xm < x0) || (xm > x1)) { gp_XYZ t[2][3]; t[0][0] = vt0.XYZ(); t[0][1] = vt0.XYZ() + xdir_along.XYZ() * arrow_head_scale + ydir.XYZ() * (arrow_head_scale * (-0.4)); t[0][2] = vt0.XYZ() + xdir_along.XYZ() * arrow_head_scale + ydir.XYZ() * (arrow_head_scale * 0.4); t[1][0] = vt1.XYZ(); t[1][1] = vt1.XYZ() + xdir_along.XYZ() * (-arrow_head_scale) + ydir.XYZ() * (arrow_head_scale * 0.4); t[1][2] = vt1.XYZ() + xdir_along.XYZ() * (-arrow_head_scale) + ydir.XYZ() * (arrow_head_scale * (-0.4)); // adjust line vertices new_vt0 = gp_Pnt(vt0.XYZ() + xdir_along.XYZ() * arrow_head_scale); new_vt1 = gp_Pnt(vt1.XYZ() + xdir_along.XYZ() * (-arrow_head_scale)); // draw two triangles for(int i = 0; i<2; i++) { glBegin(GL_LINE_STRIP); glVertex3d(t[i][0].X(), t[i][0].Y(), t[i][0].Z()); glVertex3d(t[i][1].X(), t[i][1].Y(), t[i][1].Z()); glVertex3d(t[i][2].X(), t[i][2].Y(), t[i][2].Z()); glVertex3d(t[i][0].X(), t[i][0].Y(), t[i][0].Z()); glEnd(); } } // draw side lines glBegin(GL_LINES); glVertex3d(p0.X(), p0.Y(), p0.Z()); glVertex3d(vt0.X(), vt0.Y(), vt0.Z()); glVertex3d(p1.X(), p1.Y(), p1.Z()); glVertex3d(vt1.X(), vt1.Y(), vt1.Z()); glEnd(); if(xm < x0) { // long line first gp_Pnt vt4 = vt2.XYZ() + xdir_along.XYZ() * (-long_line_extra); glBegin(GL_LINES); glVertex3d(vt2.X(), vt2.Y(), vt2.Z()); glVertex3d(new_vt0.X(), new_vt0.Y(), new_vt0.Z()); glEnd(); // little line gp_Pnt vt3 = new_vt1.XYZ() + xdir_along.XYZ() * short_line_length; glBegin(GL_LINES); glVertex3d(new_vt1.X(), new_vt1.Y(), new_vt1.Z()); glVertex3d(vt3.X(), vt3.Y(), vt3.Z()); glEnd(); } else if(xm > x1) { // little first gp_Pnt vt3 = new_vt0.XYZ() - xdir_along.XYZ() * short_line_length; glBegin(GL_LINES); glVertex3d(vt3.X(), vt3.Y(), vt3.Z()); glVertex3d(new_vt0.X(), new_vt0.Y(), new_vt0.Z()); glEnd(); // long line glBegin(GL_LINES); gp_Pnt vt4 = vt2.XYZ() + xdir_along.XYZ() * (width * scale + long_line_extra); glVertex3d(vt1.X(), vt1.Y(), vt1.Z()); glVertex3d(vt4.X(), vt4.Y(), vt4.Z()); glEnd(); } else { // draw the arrow line glBegin(GL_LINES); glVertex3d(new_vt0.X(), new_vt0.Y(), new_vt0.Z()); glVertex3d(new_vt1.X(), new_vt1.Y(), new_vt1.Z()); glEnd(); } }
void gPntToTuple(double* result, gp_Pnt& p) { result[0] = p.X(); result[1] = p.Y(); result[2] = p.Z(); }
//======================================================================= //function : HasIntersection3 //purpose : Auxilare for HasIntersection() // find intersection point between triangle (P1,P2,P3) // and segment [PC,P] //======================================================================= static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) { //cout<<"HasIntersection3"<<endl; //cout<<" PC("<<PC.X()<<","<<PC.Y()<<","<<PC.Z()<<")"<<endl; //cout<<" P("<<P.X()<<","<<P.Y()<<","<<P.Z()<<")"<<endl; //cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl; //cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl; //cout<<" P3("<<P3.X()<<","<<P3.Y()<<","<<P3.Z()<<")"<<endl; gp_Vec VP1(P1,P2); gp_Vec VP2(P1,P3); IntAna_Quadric IAQ(gp_Pln(P1,VP1.Crossed(VP2))); IntAna_IntConicQuad IAICQ(gp_Lin(PC,gp_Dir(gp_Vec(PC,P))),IAQ); if(IAICQ.IsDone()) { if( IAICQ.IsInQuadric() ) return false; if( IAICQ.NbPoints() == 1 ) { gp_Pnt PIn = IAICQ.Point(1); double preci = 1.e-6; // check if this point is internal for segment [PC,P] bool IsExternal = ( (PC.X()-PIn.X())*(P.X()-PIn.X()) > preci ) || ( (PC.Y()-PIn.Y())*(P.Y()-PIn.Y()) > preci ) || ( (PC.Z()-PIn.Z())*(P.Z()-PIn.Z()) > preci ); if(IsExternal) { return false; } // check if this point is internal for triangle (P1,P2,P3) gp_Vec V1(PIn,P1); gp_Vec V2(PIn,P2); gp_Vec V3(PIn,P3); if( V1.Magnitude()<preci || V2.Magnitude()<preci || V3.Magnitude()<preci ) { Pint = PIn; return true; } gp_Vec VC1 = V1.Crossed(V2); gp_Vec VC2 = V2.Crossed(V3); gp_Vec VC3 = V3.Crossed(V1); if(VC1.Magnitude()<preci) { if(VC2.IsOpposite(VC3,preci)) { return false; } } else if(VC2.Magnitude()<preci) { if(VC1.IsOpposite(VC3,preci)) { return false; } } else if(VC3.Magnitude()<preci) { if(VC1.IsOpposite(VC2,preci)) { return false; } } else { if( VC1.IsOpposite(VC2,preci) || VC1.IsOpposite(VC3,preci) || VC2.IsOpposite(VC3,preci) ) { return false; } } Pint = PIn; return true; } } return false; }