// Created on: 1993-07-07
// Created by: Jean Claude VAUTHIER
// Copyright (c) 1993-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
// Version:
//pmn 24/09/96 Ajout du prolongement de courbe.
// dans le cas de valeurs proportionnelles des denominateurs
// en umin umax et/ou vmin vmax.
// pmn 4/07/97 Gestion de la continuite dans BuildCurve3d (PRO9097)
-
// xab 10/07/97 on revient en arriere sur l'ajout du 26/06/97
// pmn 26/09/97 Ajout des parametres d'approx dans BuildCurve3d
// xab 29/09/97 on reintegre l'ajout du 26/06/97
// References: None
// Language: C++2.0
// Purpose:
-
// Declarations:
-#include <GeomLib.ixx>
-
-#include <Precision.hxx>
-#include <GeomConvert.hxx>
-#include <Hermit.hxx>
-#include <Standard_NotImplemented.hxx>
-#include <GeomLib_MakeCurvefromApprox.hxx>
-#include <GeomLib_DenominatorMultiplier.hxx>
-#include <GeomLib_DenominatorMultiplierPtr.hxx>
-#include <GeomLib_PolyFunc.hxx>
-#include <GeomLib_LogSample.hxx>
-
-#include <AdvApprox_ApproxAFunction.hxx>
-#include <AdvApprox_PrefAndRec.hxx>
-
#include <Adaptor2d_HCurve2d.hxx>
+#include <Adaptor3d_Curve.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <Adaptor3d_HSurface.hxx>
-#include <Adaptor3d_CurveOnSurface.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <GeomAdaptor_Surface.hxx>
-#include <GeomAdaptor_HSurface.hxx>
-#include <Geom2dAdaptor_HCurve.hxx>
-#include <Geom2dAdaptor_GHCurve.hxx>
-
-#include <Geom2d_BSplineCurve.hxx>
-#include <Geom_BSplineCurve.hxx>
+#include <AdvApprox_ApproxAFunction.hxx>
+#include <AdvApprox_PrefAndRec.hxx>
+#include <BSplCLib.hxx>
+#include <BSplSLib.hxx>
+#include <CSLib.hxx>
+#include <CSLib_NormalStatus.hxx>
+#include <ElCLib.hxx>
#include <Geom2d_BezierCurve.hxx>
-#include <Geom_BezierCurve.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_Line.hxx>
-#include <Geom2d_Line.hxx>
-#include <Geom_Circle.hxx>
+#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Circle.hxx>
-#include <Geom_Ellipse.hxx>
+#include <Geom2d_Curve.hxx>
#include <Geom2d_Ellipse.hxx>
-#include <Geom_Parabola.hxx>
-#include <Geom2d_Parabola.hxx>
-#include <Geom_Hyperbola.hxx>
#include <Geom2d_Hyperbola.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom2d_TrimmedCurve.hxx>
-#include <Geom_OffsetCurve.hxx>
+#include <Geom2d_Line.hxx>
#include <Geom2d_OffsetCurve.hxx>
+#include <Geom2d_Parabola.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom2dAdaptor_GHCurve.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <Geom2dConvert.hxx>
+#include <Geom_BezierCurve.hxx>
#include <Geom_BezierSurface.hxx>
+#include <Geom_BoundedCurve.hxx>
+#include <Geom_BoundedSurface.hxx>
+#include <Geom_BSplineCurve.hxx>
#include <Geom_BSplineSurface.hxx>
-
-#include <BSplCLib.hxx>
-#include <BSplSLib.hxx>
-#include <PLib.hxx>
-#include <math_Matrix.hxx>
-#include <math_Vector.hxx>
-#include <math_Jacobi.hxx>
-#include <math.hxx>
-#include <math_FunctionAllRoots.hxx>
-#include <math_FunctionSample.hxx>
-
-#include <TColStd_HArray1OfReal.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <TColgp_Array1OfVec.hxx>
-#include <TColgp_Array2OfPnt.hxx>
-#include <TColgp_HArray2OfPnt.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TColgp_Array1OfXYZ.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_Array2OfReal.hxx>
-#include <TColStd_HArray2OfReal.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-
-#include <gp_TrsfForm.hxx>
-#include <gp_Lin.hxx>
-#include <gp_Lin2d.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Ellipse.hxx>
+#include <Geom_Hyperbola.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_OffsetCurve.hxx>
+#include <Geom_Parabola.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <GeomConvert.hxx>
+#include <GeomConvert_ApproxSurface.hxx>
+#include <GeomConvert_CompCurveToBSplineCurve.hxx>
+#include <GeomLib.hxx>
+#include <GeomLib_DenominatorMultiplier.hxx>
+#include <GeomLib_DenominatorMultiplierPtr.hxx>
+#include <GeomLib_LogSample.hxx>
+#include <GeomLib_MakeCurvefromApprox.hxx>
+#include <GeomLib_PolyFunc.hxx>
+#include <gp_Ax2.hxx>
#include <gp_Circ.hxx>
#include <gp_Circ2d.hxx>
+#include <gp_Dir.hxx>
#include <gp_Elips.hxx>
#include <gp_Elips2d.hxx>
+#include <gp_GTrsf2d.hxx>
#include <gp_Hypr.hxx>
#include <gp_Hypr2d.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Lin2d.hxx>
#include <gp_Parab.hxx>
#include <gp_Parab2d.hxx>
-#include <gp_GTrsf2d.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
#include <gp_Trsf2d.hxx>
-
-#include <ElCLib.hxx>
-#include <Geom2dConvert.hxx>
-#include <GeomConvert_CompCurveToBSplineCurve.hxx>
-#include <GeomConvert_ApproxSurface.hxx>
-
-
+#include <gp_TrsfForm.hxx>
+#include <gp_Vec.hxx>
+#include <Hermit.hxx>
+#include <math.hxx>
+#include <math_FunctionAllRoots.hxx>
+#include <math_FunctionSample.hxx>
+#include <math_Jacobi.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
+#include <PLib.hxx>
+#include <Precision.hxx>
#include <Standard_ConstructionError.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+#include <TColgp_Array1OfVec.hxx>
+#include <TColgp_Array1OfXYZ.hxx>
+#include <TColgp_Array2OfPnt.hxx>
+#include <TColgp_HArray2OfPnt.hxx>
+#include <TColStd_Array1OfInteger.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_Array2OfReal.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+#include <TColStd_HArray2OfReal.hxx>
//=======================================================================
//function : ComputeLambda
}
#include <Extrema_LocateExtPC.hxx>
+#include <Geom2d_Curve.hxx>
//=======================================================================
//function : RemovePointsFromArray
//purpose :
{
if(CurvePtr.IsNull()) Standard_Failure::Raise();
if (Abs(LastOnCurve - RequestedLast) <= Tolerance &&
- Abs(FirstOnCurve - RequestedFirst) <= Tolerance) {
- NewCurvePtr = CurvePtr;
- return;
+ Abs(FirstOnCurve - RequestedFirst) <= Tolerance)
+ {
+ NewCurvePtr = CurvePtr;
+ return;
}
// the parametrisation lentgh must at least be the same.
if (Abs(LastOnCurve - FirstOnCurve - RequestedLast + RequestedFirst)
- <= Tolerance) {
- if (CurvePtr->IsKind(STANDARD_TYPE(Geom2d_Line))) {
+ <= Tolerance)
+ {
+ if (CurvePtr->IsKind(STANDARD_TYPE(Geom2d_Line)))
+ {
Handle(Geom2d_Line) Line =
- Handle(Geom2d_Line)::DownCast(CurvePtr->Copy());
+ Handle(Geom2d_Line)::DownCast(CurvePtr->Copy());
Standard_Real dU = FirstOnCurve - RequestedFirst;
gp_Dir2d D = Line->Direction() ;
Line->Translate(dU * gp_Vec2d(D));
NewCurvePtr = Line;
}
- else if (CurvePtr->IsKind(STANDARD_TYPE(Geom2d_Circle))) {
+ else if (CurvePtr->IsKind(STANDARD_TYPE(Geom2d_Circle)))
+ {
gp_Trsf2d Trsf;
NewCurvePtr = Handle(Geom2d_Curve)::DownCast(CurvePtr->Copy());
Handle(Geom2d_Circle) Circ =
- Handle(Geom2d_Circle)::DownCast(NewCurvePtr);
+ Handle(Geom2d_Circle)::DownCast(NewCurvePtr);
gp_Pnt2d P = Circ->Location();
Standard_Real dU;
if (Circ->Circ2d().IsDirect()) {
- dU = FirstOnCurve - RequestedFirst;
+ dU = FirstOnCurve - RequestedFirst;
}
else {
- dU = RequestedFirst - FirstOnCurve;
+ dU = RequestedFirst - FirstOnCurve;
}
Trsf.SetRotation(P,dU);
NewCurvePtr->Transform(Trsf) ;
}
- else if (CurvePtr->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
+ else if (CurvePtr->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+ {
Handle(Geom2d_TrimmedCurve) TC =
- Handle(Geom2d_TrimmedCurve)::DownCast(CurvePtr);
+ Handle(Geom2d_TrimmedCurve)::DownCast(CurvePtr);
GeomLib::SameRange(Tolerance,
- TC->BasisCurve(),
- FirstOnCurve , LastOnCurve,
- RequestedFirst, RequestedLast,
- NewCurvePtr);
+ TC->BasisCurve(),
+ FirstOnCurve , LastOnCurve,
+ RequestedFirst, RequestedLast,
+ NewCurvePtr);
NewCurvePtr = new Geom2d_TrimmedCurve( NewCurvePtr, RequestedFirst, RequestedLast );
}
-//
-// attention a des problemes de limitation : utiliser le MEME test que dans
-// Geom2d_TrimmedCurve::SetTrim car sinon comme on risque de relimite sur
-// RequestedFirst et RequestedLast on aura un probleme
-//
-//
+ //
+ // attention a des problemes de limitation : utiliser le MEME test que dans
+ // Geom2d_TrimmedCurve::SetTrim car sinon comme on risque de relimite sur
+ // RequestedFirst et RequestedLast on aura un probleme
+ //
+ //
else if (Abs(LastOnCurve - FirstOnCurve) > Precision::PConfusion() ||
- Abs(RequestedLast + RequestedFirst) > Precision::PConfusion()) {
-
+ Abs(RequestedLast + RequestedFirst) > Precision::PConfusion())
+ {
+
Handle(Geom2d_TrimmedCurve) TC =
- new Geom2d_TrimmedCurve(CurvePtr,FirstOnCurve,LastOnCurve);
-
+ new Geom2d_TrimmedCurve(CurvePtr,FirstOnCurve,LastOnCurve);
+
Handle(Geom2d_BSplineCurve) BS =
- Geom2dConvert::CurveToBSplineCurve(TC);
+ Geom2dConvert::CurveToBSplineCurve(TC);
TColStd_Array1OfReal Knots(1,BS->NbKnots());
BS->Knots(Knots);
-
+
BSplCLib::Reparametrize(RequestedFirst,RequestedLast,Knots);
-
+
BS->SetKnots(Knots);
NewCurvePtr = BS;
}
-
}
- else { // On segmente le resultat
- Handle(Geom2d_TrimmedCurve) TC =
- new Geom2d_TrimmedCurve( CurvePtr, FirstOnCurve, LastOnCurve );
+ else
+ { // On segmente le resultat
+ Handle(Geom2d_TrimmedCurve) TC;
+ Handle(Geom2d_Curve) aCCheck = CurvePtr;
- Standard_Real newFirstOnCurve = TC->FirstParameter(), newLastOnCurve = TC->LastParameter();
-
- Handle(Geom2d_BSplineCurve) BS =
- Geom2dConvert::CurveToBSplineCurve(TC);
+ if(aCCheck->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+ {
+ aCCheck = Handle(Geom2d_TrimmedCurve)::DownCast(aCCheck)->BasisCurve();
+ }
- if (BS->IsPeriodic())
- BS->Segment( newFirstOnCurve, newLastOnCurve) ;
- else
- BS->Segment( Max(newFirstOnCurve, BS->FirstParameter()),
- Min(newLastOnCurve, BS->LastParameter()) );
+ if(aCCheck->IsPeriodic())
+ {
+ TC = new Geom2d_TrimmedCurve( CurvePtr, FirstOnCurve, LastOnCurve );
+ }
+ else
+ {
+ const Standard_Real Udeb = Max(CurvePtr->FirstParameter(), FirstOnCurve);
+ const Standard_Real Ufin = Min(CurvePtr->LastParameter(), LastOnCurve);
+
+ TC = new Geom2d_TrimmedCurve( CurvePtr, Udeb, Ufin );
+ }
+ //
+ Handle(Geom2d_BSplineCurve) BS =
+ Geom2dConvert::CurveToBSplineCurve(TC);
TColStd_Array1OfReal Knots(1,BS->NbKnots());
BS->Knots(Knots);
-
+
BSplCLib::Reparametrize(RequestedFirst,RequestedLast,Knots);
-
+
BS->SetKnots(Knots);
NewCurvePtr = BS;
}
Standard_Integer *DerivativeRequest,
Standard_Real *Result,// [Dimension]
Standard_Integer *ReturnCode)
-{
- register Standard_Integer ii ;
- gp_Pnt Point ;
+{
+ gp_Pnt Point;
//Gestion des positionnements gauche / droite
if ((DebutFin[0] != FirstParam) || (DebutFin[1] != LastParam))
{
TrimCurve->D0((*Parameter), Point) ;
- for (ii = 0 ; ii < 3 ; ii++)
+ for (Standard_Integer ii = 0 ; ii < 3 ; ii++)
Result[ii] = Point.Coord(ii + 1);
}
if (*DerivativeRequest == 1)
{
gp_Vec Vector;
TrimCurve->D1((*Parameter), Point, Vector);
- for (ii = 0 ; ii < 3 ; ii++)
+ for (Standard_Integer ii = 0 ; ii < 3 ; ii++)
Result[ii] = Vector.Coord(ii + 1) ;
}
if (*DerivativeRequest == 2)
{
gp_Vec Vector, VecBis;
TrimCurve->D2((*Parameter), Point, VecBis, Vector);
- for (ii = 0 ; ii < 3 ; ii++)
+ for (Standard_Integer ii = 0 ; ii < 3 ; ii++)
Result[ii] = Vector.Coord(ii + 1) ;
}
ReturnCode[0] = 0;
Adaptor3d_CurveOnSurface& Curve,
const Standard_Real FirstParameter,
const Standard_Real LastParameter,
- Handle_Geom_Curve& NewCurvePtr,
+ Handle(Geom_Curve)& NewCurvePtr,
Standard_Real& MaxDeviation,
Standard_Real& AverageDeviation,
const GeomAbs_Shape Continuity,
Standard_Integer curve_not_computed = 1 ;
MaxDeviation = 0.0e0 ;
AverageDeviation = 0.0e0 ;
- const Handle(GeomAdaptor_HSurface) & geom_adaptor_surface_ptr =
- Handle(GeomAdaptor_HSurface)::DownCast(Curve.GetSurface()) ;
- const Handle(Geom2dAdaptor_HCurve) & geom_adaptor_curve_ptr =
- Handle(Geom2dAdaptor_HCurve)::DownCast(Curve.GetCurve()) ;
+ Handle(GeomAdaptor_HSurface) geom_adaptor_surface_ptr (Handle(GeomAdaptor_HSurface)::DownCast(Curve.GetSurface()) );
+ Handle(Geom2dAdaptor_HCurve) geom_adaptor_curve_ptr (Handle(Geom2dAdaptor_HCurve)::DownCast(Curve.GetCurve()) );
if (! geom_adaptor_curve_ptr.IsNull() &&
! geom_adaptor_surface_ptr.IsNull()) {
GeomAbs_Shape UCont = GeomAbs_C1, VCont = GeomAbs_C1;
Standard_Integer degU = 14, degV = 14;
Standard_Integer nmax = 16;
- Standard_Integer thePrec = 1;
- GeomConvert_ApproxSurface theApprox(Surface,Tol,UCont,VCont,degU,degV,nmax,thePrec);
+ Standard_Integer thePrec = 1;
+ const Handle(Geom_Surface)& aSurf = Surface; // to resolve ambiguity
+ GeomConvert_ApproxSurface theApprox(aSurf,Tol,UCont,VCont,degU,degV,nmax,thePrec);
if (theApprox.HasResult())
BS = theApprox.Surface();
else
- Standard_Integer Cdeg, Cdim, NbP, Ksize, Psize ;
+ Standard_Integer Cdeg = 0, Cdim = 0, NbP = 0, Ksize = 0, Psize = 1;
Standard_Integer ii, jj, ipole, Kount;
Standard_Real Tbord, lambmin=Length;
- Standard_Real * Padr;
+ Standard_Real * Padr = NULL;
Standard_Boolean Ok;
Handle(TColStd_HArray1OfReal) FKnots, Point, lambda, Tgte, Poles;
}
// tableaux necessaires pour l'extension
- Standard_Integer Ksize2 = Ksize+Cdeg, NbPoles, NbKnots;
+ Standard_Integer Ksize2 = Ksize+Cdeg, NbPoles, NbKnots = 0;
TColStd_Array1OfReal FK(1, Ksize2) ;
Standard_Real * FKRadr = &FK(1);
NewP(ii,jj).SetCoord(3,PRes(indice+2));
if (rational) {
ww = PRes(indice+3);
+ if (Abs(ww - 1.0) < EpsW)
+ ww = 1.0;
if (ww < EpsW) {
NullWeight = Standard_True;
}
NewP(ii,jj).SetCoord(3,PRes(indice+2));
if (rational) {
ww = PRes(indice+3);
+ if (Abs(ww - 1.0) < EpsW)
+ ww = 1.0;
if (ww < EpsW) {
NullWeight = Standard_True;
}
}
if (NullWeight) {
-#if DEB
+#ifdef OCCT_DEBUG
cout << "Echec de l'Extension rationnelle" << endl;
#endif
lambmin /= 3.;
math_Jacobi J(M);
if (!J.IsDone()) {
-#if DEB
+#ifdef OCCT_DEBUG
cout << "Erreur dans Jacobbi" << endl;
M.Dump(cout);
#endif
BSurf->VDegree(),
surface_u_knots,
surface_v_knots,
- surface_u_mults,
- surface_v_mults,
+ &surface_u_mults,
+ &surface_v_mults,
surface_poles,
- surface_weights,
+ &surface_weights,
newuflatknots,
newvflatknots,
BSurf->UDegree()+3,
Standard_Real MDU = DU.SquareMagnitude(), MDV = DV.SquareMagnitude();
- Standard_Real h, sign;
- Standard_Boolean AlongV;
- Handle(Geom_Curve) Iso;
- Standard_Real t, first, last, bid1, bid2;
- gp_Vec Tang;
-
if(MDU >= aTol2 && MDV >= aTol2) {
gp_Vec Norm = DU^DV;
Standard_Real Magn = Norm.SquareMagnitude();
return 0;
}
- else if(MDU < aTol2 && MDV >= aTol2) {
- AlongV = Standard_True;
- Iso = S->UIso(UV.X());
- t = UV.Y();
- S->Bounds(bid1, bid2, first, last);
- }
- else if(MDU >= aTol2 && MDV < aTol2) {
- AlongV = Standard_False;
- Iso = S->VIso(UV.Y());
- t = UV.X();
- S->Bounds(first, last, bid1, bid2);
- }
- else {
- return 3;
- }
-
- Standard_Real L = .001;
-
- if(Precision::IsInfinite(Abs(first))) first = t - 1.;
- if(Precision::IsInfinite(Abs(last))) last = t + 1.;
-
- if(last - t >= t - first) {
- sign = 1.;
- }
else {
- sign = -1.;
- }
-
- Standard_Real hmax = .01*(last - first);
- if(AlongV) {
- h = Min(L/sqrt(MDV), hmax);
- S->D1(UV.X(), UV.Y() + sign*h, DummyPnt, DU, DV);
- }
- else {
- h = Min(L/sqrt(MDU), hmax);
- S->D1(UV.X() + sign*h, UV.Y(), DummyPnt, DU, DV);
- }
-
- gp_Vec DD;
-
- gp_Vec NAux = DU^DV;
- Standard_Real h1 = h;
- while(NAux.SquareMagnitude() < aTol2) {
- h1 += h;
- if(AlongV) {
- Standard_Real v = UV.Y() + sign*h1;
-
- if(v < first || v > last) return 3;
-
- S->D1(UV.X(), v, DummyPnt, DU, DV);
- }
- else {
- Standard_Real v = UV.X() + sign*h1;
-
- if(v < first || v > last) return 3;
-
- S->D1(v, UV.Y(), DummyPnt, DU, DV);
-
- }
- NAux = DU^DV;
- }
-
-
- Iso->D2(t, DummyPnt, Tang, DD);
-
- if(DD.SquareMagnitude() >= aTol2) {
- gp_Vec NV = DD * (Tang * Tang) - Tang * (Tang * DD);
- Standard_Real MagnNV = NV.SquareMagnitude();
- if(MagnNV < aTol2) return 3;
-
- MagnNV = sqrt(MagnNV);
- N.SetXYZ(NV.XYZ()/MagnNV);
-
- Standard_Real par = .5*(bid2+bid1);
-
- if(AlongV) {
- Iso = S->UIso(par);
- }
- else {
- Iso = S->VIso(par);
- }
-
- Iso->D2(t, DummyPnt, Tang, DD);
-
- gp_Vec N1V = DD * (Tang * Tang) - Tang * (Tang * DD);
- Standard_Real MagnN1V = N1V.SquareMagnitude();
- if(MagnN1V < aTol2) return 3;
-
- MagnN1V = sqrt(MagnN1V);
- gp_Dir N1(N1V.XYZ()/MagnN1V);
-
- Standard_Integer res = 1;
+ gp_Vec D2U, D2V, D2UV;
+ Standard_Boolean isDone;
+ CSLib_NormalStatus aStatus;
+ gp_Dir aNormal;
+
+ S->D2(UV.X(), UV.Y(), DummyPnt, DU, DV, D2U, D2V, D2UV);
+ CSLib::Normal(DU, DV, D2U, D2V, D2UV, Tol, isDone, aStatus, aNormal);
+
+ if (isDone) {
+ Standard_Real Umin, Umax, Vmin, Vmax;
+ Standard_Real step = 1.0e-5;
+ Standard_Real eps = 1.0e-16;
+ Standard_Real sign = -1.0;
+
+ S->Bounds(Umin, Umax, Vmin, Vmax);
+
+ // check for cone apex singularity point
+ if ((UV.Y() > Vmin + step) && (UV.Y() < Vmax - step))
+ {
+ gp_Dir aNormal1, aNormal2;
+ Standard_Real aConeSingularityAngleEps = 1.0e-4;
+ S->D1(UV.X(), UV.Y() - sign * step, DummyPnt, DU, DV);
+ if ((DU.XYZ().SquareModulus() > eps) && (DV.XYZ().SquareModulus() > eps)) {
+ aNormal1 = DU^DV;
+ S->D1(UV.X(), UV.Y() + sign * step, DummyPnt, DU, DV);
+ if ((DU.XYZ().SquareModulus() > eps) && (DV.XYZ().SquareModulus() > eps)) {
+ aNormal2 = DU^DV;
+ if (aNormal1.IsOpposite(aNormal2, aConeSingularityAngleEps))
+ return 2;
+ }
+ }
+ }
- if(N*N1 < 1. - Tol) res = 2;
+ // Along V
+ if(MDU < aTol2 && MDV >= aTol2) {
+ if ((Vmax - UV.Y()) > (UV.Y() - Vmin))
+ sign = 1.0;
+ S->D1(UV.X(), UV.Y() + sign * step, DummyPnt, DU, DV);
+ gp_Vec Norm = DU^DV;
+ if (Norm.SquareMagnitude() < eps) {
+ Standard_Real sign1 = -1.0;
+ if ((Umax - UV.X()) > (UV.X() - Umin))
+ sign1 = 1.0;
+ S->D1(UV.X() + sign1 * step, UV.Y() + sign * step, DummyPnt, DU, DV);
+ Norm = DU^DV;
+ }
+ if ((Norm.SquareMagnitude() >= eps) && (Norm.Dot(aNormal) < 0.0))
+ aNormal.Reverse();
+ }
- if(N*NAux <= 0.) N.Reverse();
+ // Along U
+ if(MDV < aTol2 && MDU >= aTol2) {
+ if ((Umax - UV.X()) > (UV.X() - Umin))
+ sign = 1.0;
+ S->D1(UV.X() + sign * step, UV.Y(), DummyPnt, DU, DV);
+ gp_Vec Norm = DU^DV;
+ if (Norm.SquareMagnitude() < eps) {
+ Standard_Real sign1 = -1.0;
+ if ((Vmax - UV.Y()) > (UV.Y() - Vmin))
+ sign1 = 1.0;
+ S->D1(UV.X() + sign * step, UV.Y() + sign1 * step, DummyPnt, DU, DV);
+ Norm = DU^DV;
+ }
+ if ((Norm.SquareMagnitude() >= eps) && (Norm.Dot(aNormal) < 0.0))
+ aNormal.Reverse();
+ }
- return res;
- }
- else {
- //Seems to be conical singular point
-
- if(AlongV) {
- NAux = DU^Tang;
+ // quasysingular
+ if ((aStatus == CSLib_D1NuIsNull) || (aStatus == CSLib_D1NvIsNull) ||
+ (aStatus == CSLib_D1NuIsParallelD1Nv)) {
+ N.SetXYZ(aNormal.XYZ());
+ return 1;
+ }
+ // conical
+ if (aStatus == CSLib_InfinityOfSolutions)
+ return 2;
}
+ // computation is impossible
else {
- NAux = Tang^DV;
+ // conical
+ if (aStatus == CSLib_D1NIsNull) {
+ return 2;
+ }
+ return 3;
}
-
- sign = NAux.Magnitude();
-
- if(sign < Tol) return 3;
-
- N = NAux;
-
- return 2;
-
}
-
+ return 3;
}