BRepFill_Sweep Sweep(mySec, myLoc, Standard_True);
Sweep.SetTolerance(myTol);
Sweep.SetAngularControl(angmin, angmax);
- Sweep.Build(myStyle, GeomFill_Location, myCont);
+ Sweep.Build(myStyle, myCont);
if (Sweep.IsDone()) {
myShape = Sweep.Shape();
myShell = TopoDS::Shell(myShape);
Edge from TopoDS,
Vertex from TopoDS,
Pnt from gp,
- Trsf from gp
-
+ Trsf from gp,
+ Trihedron from GeomFill
raises
DomainError from Standard,
GeneratePartCase : Boolean from Standard = Standard_False)
returns Pipe from BRepFill;
+ SetMode(me : in out;
+ aMode : Trihedron from GeomFill);
+ ---Purpose: Set the mode of sweeping
+ -- It can be:
+ -- - Frenet
+ -- - Corrected Frenet
+ -- - Discrete Trihedron
+ -- By default the mode is Corrected Frenet
+
+ SetForceApproxC1(me : in out;
+ ForceApproxC1 : Boolean from Standard);
+ ---Purpose: Set the flag that indicates attempt to approximate
+ -- a C1-continuous surface if a swept surface proved
+ -- to be C0.
+
Perform (me : in out; Spine : Wire from TopoDS;
Profile : Shape from TopoDS;
GeneratePartCase : Boolean from Standard = Standard_False)
myDegmax : Integer from Standard;
mySegmax : Integer from Standard;
+ myMode : Trihedron from GeomFill;
+ myForceApproxC1 : Boolean from Standard;
+
end Pipe;
#include <BRepTools_Substitution.hxx>
#include <GeomFill_CorrectedFrenet.hxx>
+#include <GeomFill_Frenet.hxx>
+#include <GeomFill_DiscreteTrihedron.hxx>
#include <GeomFill_CurveAndTrihedron.hxx>
#include <BRepFill_SectionPlacement.hxx>
{
myDegmax = 10;
mySegmax = 100;
+ myMode = GeomFill_IsCorrectedFrenet;
+ myForceApproxC1 = Standard_False;
}
{
myDegmax = 10;
mySegmax = 100;
+ myMode = GeomFill_IsCorrectedFrenet;
+ myForceApproxC1 = Standard_False;
Perform(Spine, Profile, KPart);
}
+//=======================================================================
+//function : SetMode
+//purpose : Set the mode of sweeping
+// It can be:
+// - Frenet
+// - Corrected Frenet
+// - Discrete Trihedron
+//=======================================================================
+
+void BRepFill_Pipe::SetMode(const GeomFill_Trihedron aMode)
+{
+ if (aMode == GeomFill_IsFrenet ||
+ aMode == GeomFill_IsCorrectedFrenet ||
+ aMode == GeomFill_IsDiscreteTrihedron)
+ myMode = aMode;
+}
+
+//=======================================================================
+//function : SetForceApproxC1
+//purpose : Set the flag that indicates attempt to approximate
+// a C1-continuous surface if a swept surface proved
+// to be C0.
+//=======================================================================
+
+void BRepFill_Pipe::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
+{
+ myForceApproxC1 = ForceApproxC1;
+}
//=======================================================================
BRepTools_WireExplorer wexp;
TopoDS_Shape TheProf;
-
- Handle(GeomFill_CorrectedFrenet) TLaw =
- new (GeomFill_CorrectedFrenet) ();
+ Handle(GeomFill_TrihedronLaw) TLaw;
+ switch (myMode)
+ {
+ case GeomFill_IsFrenet:
+ TLaw = new GeomFill_Frenet();
+ break;
+ case GeomFill_IsCorrectedFrenet:
+ TLaw = new GeomFill_CorrectedFrenet();
+ break;
+ case GeomFill_IsDiscreteTrihedron:
+ TLaw = new GeomFill_DiscreteTrihedron();
+ break;
+ }
Handle(GeomFill_CurveAndTrihedron) Loc =
new (GeomFill_CurveAndTrihedron) (TLaw);
myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
// Sweeping
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
- MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
+ MkSw.SetForceApproxC1(myForceApproxC1);
+ MkSw.Build( BRepFill_Modified, GeomAbs_C2, GeomFill_Location, myDegmax, mySegmax );
TopoDS_Shape aLocalShape = MkSw.Shape();
return TopoDS::Wire(aLocalShape);
// return TopoDS::Wire(MkSw.Shape());
Handle(BRepFill_ShapeLaw) Section =
new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
- MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
+ MkSw.SetForceApproxC1(myForceApproxC1);
+ MkSw.Build( BRepFill_Modified, GeomAbs_C2, GeomFill_Location, myDegmax, mySegmax );
result = MkSw.Shape();
}
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
MkSw.SetBounds(TopoDS::Wire(TheFirst),
TopoDS::Wire(TheLast));
- MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
+ MkSw.SetForceApproxC1(myForceApproxC1);
+ MkSw.Build( BRepFill_Modified, GeomAbs_C2, GeomFill_Location, myDegmax, mySegmax );
result = MkSw.Shape();
// Labeling of elements
---Level: Public
---See Also:GeomFill_IsCorrectedFrenet
+ SetDiscrete(me : mutable);
+ ---Purpose: Set a Discrete trihedron
+ -- to perform the sweeping
+ ---Level: Public
+ ---See Also:GeomFill_IsDiscreteTrihedron
+
Set(me : mutable; Axe : Ax2 from gp);
---Purpose: Set an fixed trihedron to perform the sweeping
-- all sections will be parallel.
---Level: Public
+ SetForceApproxC1(me : mutable;
+ ForceApproxC1 : Boolean from Standard);
+ ---Purpose: Set the flag that indicates attempt to approximate
+ -- a C1-continuous surface if a swept surface proved
+ -- to be C0.
+
+
-- =================================
-- Methodes to define section(s)
-- =================================
myTol3d : Real;
myBoundTol : Real;
- myTolAngular : Real;
+ myTolAngular : Real;
angmin, angmax : Real;
+ myForceApproxC1 : Boolean;
myLaw : Function from Law;
myLocation : LocationLaw from BRepFill;
#include <GeomFill_TrihedronLaw.hxx>
#include <GeomFill_CorrectedFrenet.hxx>
#include <GeomFill_Frenet.hxx>
+#include <GeomFill_DiscreteTrihedron.hxx>
#include <GeomFill_Fixed.hxx>
#include <GeomFill_ConstantBiNormal.hxx>
#include <GeomFill_SectionLaw.hxx>
: mySpine(Spine),
myTrihedron(GeomFill_IsCorrectedFrenet),
myTransition(BRepFill_Modified),
+ myForceApproxC1(Standard_False),
myStatus(GeomFill_PipeOk)
{
myLocation.Nullify();
mySection.Nullify(); //It is required to relocalize sections.
}
+//=======================================================================
+//function : SetDiscrete
+//purpose : Define a law of Discrete Trihedron
+//=======================================================================
+ void BRepFill_PipeShell::SetDiscrete()
+{
+ Handle(GeomFill_TrihedronLaw) TLaw;
+
+ myTrihedron = GeomFill_IsDiscreteTrihedron;
+ TLaw = new (GeomFill_DiscreteTrihedron) ();
+
+ Handle(GeomFill_CurveAndTrihedron) Loc =
+ new (GeomFill_CurveAndTrihedron) (TLaw);
+ myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
+ mySection.Nullify(); //It is required to relocalize sections.
+}
+
//=======================================================================
//function : Set
//purpose : Define a law Constant
mySection.Nullify(); //It is required to relocalize the sections.
}
+//=======================================================================
+//function : SetForceApproxC1
+//purpose : Set the flag that indicates attempt to approximate
+// a C1-continuous surface if a swept surface proved
+// to be C0.
+//=======================================================================
+void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
+{
+ myForceApproxC1 = ForceApproxC1;
+}
+
//=======================================================================
//function : Add
//purpose : Add a Section
BRepFill_Sweep MkSw(mySection, myLocation, Standard_True);
MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular);
MkSw.SetAngularControl(angmin, angmax);
+ MkSw.SetForceApproxC1(myForceApproxC1);
MkSw.SetBounds(TopoDS::Wire(myFirst),
TopoDS::Wire(myLast));
- MkSw.Build(myTransition);
+ GeomAbs_Shape theContinuity = GeomAbs_C2;
+ if (myTrihedron == GeomFill_IsDiscreteTrihedron)
+ theContinuity = GeomAbs_C0;
+ MkSw.Build(myTransition, theContinuity);
myStatus = myLocation->GetStatus();
Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk));
-- Transition "Round" replace the Transition "Right"
is static;
+ SetForceApproxC1(me: in out;
+ ForceApproxC1 : Boolean from Standard);
+ ---Purpose: Set the flag that indicates attempt to approximate
+ -- a C1-continuous surface if a swept surface proved
+ -- to be C0.
+
+
Build(me : in out;
Transition : TransitionStyle = BRepFill_Modified;
- Approx : ApproxStyle = GeomFill_Location;
Continuity : Shape from GeomAbs = GeomAbs_C2;
+ Approx : ApproxStyle = GeomFill_Location;
Degmax : Integer = 11;
Segmax : Integer = 30);
myContinuity : Shape from GeomAbs;
myDegmax : Integer;
mySegmax : Integer;
+ myForceApproxC1 : Boolean;
myShape : Shape from TopoDS;
myLoc : LocationLaw from BRepFill;
mySec : SectionLaw from BRepFill;
myContinuity = GeomAbs_C2;
myDegmax = 11;
mySegmax = 30;
+ myForceApproxC1 = Standard_False;
}
//=======================================================================
myAngMax = Min (MaxAngle, 6.28);
}
+//=======================================================================
+//function : SetForceApproxC1
+//purpose : Set the flag that indicates attempt to approximate
+// a C1-continuous surface if a swept surface proved
+// to be C0.
+//=======================================================================
+ void BRepFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
+{
+ myForceApproxC1 = ForceApproxC1;
+}
+
///=======================================================================
//function : CorrectApproxParameters
//purpose :
// Curve by iso value
GeomFill_Sweep Sweep(myLoc->Law(ipath), KPart);
Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
+ Sweep.SetForceApproxC1(myForceApproxC1);
Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax);
if (!Sweep.IsDone())
return Standard_False;
GeomFill_Sweep Sweep(myLoc->Law(IPath), KPart);
Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
+ Sweep.SetForceApproxC1(myForceApproxC1);
// Case of evolutionary section, definition of parametric correspondence
if (!constSection) {
//purpose : Construt the result of sweeping
//======================================================================
void BRepFill_Sweep::Build(const BRepFill_TransitionStyle Transition,
- const GeomFill_ApproxStyle Approx,
const GeomAbs_Shape Continuity,
+ const GeomFill_ApproxStyle Approx,
const Standard_Integer Degmax,
const Standard_Integer Segmax)
{
- myApproxStyle = Approx;
myContinuity = Continuity;
+ myApproxStyle = Approx;
myDegmax = Degmax;
mySegmax = Segmax;
StdFail,
gp,
GeomAbs,
- Geom,
+ Geom,
+ GeomFill,
Approx,
TopoDS,
TopTools,
-- with G1 continuous spines only.
uses
Pipe from BRepFill,
+ Trihedron from GeomFill,
Wire from TopoDS,
Shape from TopoDS,
Edge from TopoDS,
-- composite solid.
returns MakePipe from BRepOffsetAPI;
+ SetMode(me : in out;
+ aMode : Trihedron from GeomFill);
+ ---Purpose: Set the mode of sweeping
+ -- It can be:
+ -- - Frenet
+ -- - Corrected Frenet
+ -- - Discrete Trihedron
+ -- By default the mode is Corrected Frenet
+
+ SetForceApproxC1(me : in out;
+ ForceApproxC1 : Boolean from Standard);
+ ---Purpose: Set the flag that indicates attempt to approximate
+ -- a C1-continuous surface if a swept surface proved
+ -- to be C0.
+
Pipe(me) returns Pipe from BRepFill
---C++: return const &
Build();
}
+//=======================================================================
+//function : SetMode
+//purpose : Set the mode of sweeping
+// It can be:
+// - Frenet
+// - Corrected Frenet
+// - Discrete Trihedron
+//=======================================================================
+
+void BRepOffsetAPI_MakePipe::SetMode(const GeomFill_Trihedron aMode)
+{
+ myPipe.SetMode(aMode);
+}
+
+//=======================================================================
+//function : SetForceApproxC1
+//purpose : Set the flag that indicates attempt to approximate
+// a C1-continuous surface if a swept surface proved
+// to be C0.
+//=======================================================================
+
+void BRepOffsetAPI_MakePipe::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
+{
+ myPipe.SetForceApproxC1(ForceApproxC1);
+}
+
//=======================================================================
//function : Pipe
//purpose :
-- to perform the sweeping
-- If IsFrenet is false, a corrected Frenet trihedron is used.
+ SetDiscreteMode(me : in out);
+ ---Purpose: Sets a Discrete trihedron
+ -- to perform the sweeping
+
SetMode(me : in out; Axe : Ax2 from gp);
---Purpose: Sets a fixed trihedron to perform the sweeping
-- all sections will be parallel.
---Level: Public
+
-- =================================
-- Methodes to define section(s)
-- =================================
-- - boundary tolerance BoundTol
-- - angular tolerance TolAngular.
+ SetForceApproxC1(me : in out;
+ ForceApproxC1 : Boolean from Standard);
+ ---Purpose: Set the flag that indicates attempt to approximate
+ -- a C1-continuous surface if a swept surface proved
+ -- to be C0.
+
SetTransitionMode(me : in out;
Mode :TransitionMode from BRepBuilderAPI = BRepBuilderAPI_Transformed)
---Purpose: Sets the transition mode to manage discontinuities on
myPipe->Set(IsFrenet);
}
+//=======================================================================
+//function : SetDiscreteMode
+//purpose :
+//=======================================================================
+ void BRepOffsetAPI_MakePipeShell::SetDiscreteMode()
+{
+ myPipe->SetDiscrete();
+}
+
//=======================================================================
//function : SetMode
//purpose :
}
return Status;
}
+
//=======================================================================
-//function : SetTransitionMode
+//function : SetTolerance
//purpose :
//=======================================================================
void BRepOffsetAPI_MakePipeShell::SetTolerance(const Standard_Real Tol3d,
myPipe->SetTolerance(Tol3d, BoundTol, TolAngular);
}
+//=======================================================================
+//function : SetForceApproxC1
+//purpose : Set the flag that indicates attempt to approximate
+// a C1-continuous surface if a swept surface proved
+// to be C0.
+//=======================================================================
+ void BRepOffsetAPI_MakePipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
+{
+ myPipe->SetForceApproxC1(ForceApproxC1);
+}
+
//=======================================================================
//function : SetTransitionMode
//purpose :
di << " -FR : Tangent and Normal are given by Frenet trihedron" <<"\n";
di << " -CF : Tangente is given by Frenet," << "\n";
di << " the Normal is computed to minimize the torsion " << "\n";
+ di << " -DT : discrete trihedron" << "\n";
di << " -DX Surf : Tangent and Normal are given by Darboux trihedron," <<"\n";
di << " Surf have to be a shell or a face" <<"\n";
di << " -CN dx dy dz : BiNormal is given by dx dy dz" << "\n";
else if (!strcmp(a[1],"-CF")) {
Sweep->SetMode(Standard_False);
}
+ else if (!strcmp(a[1],"-DT")) {
+ Sweep->SetDiscreteMode();
+ }
else if (!strcmp(a[1],"-DX")) {
if (n!=3) {
//cout << "bad arguments !" << endl;
enumeration Trihedron
is IsCorrectedFrenet, IsFixed, IsFrenet, IsConstantNormal, IsDarboux,
IsGuideAC, IsGuidePlan,
- IsGuideACWithContact, IsGuidePlanWithContact end;
+ IsGuideACWithContact, IsGuidePlanWithContact, IsDiscreteTrihedron end;
class Filling;
---Purpose: Root class for Filling;
class SequenceOfTrsf
instantiates Sequence from TCollection (Trsf from gp);
+ class SequenceOfAx2
+ instantiates Sequence from TCollection (Ax2 from gp);
+
+ class HSequenceOfAx2
+ instantiates HSequence from TCollection (Ax2 from gp,
+ SequenceOfAx2 from GeomFill);
+
--
-- private classes
--
class Fixed;
class Frenet;
class CorrectedFrenet;
+ class DiscreteTrihedron;
class ConstantBiNormal;
class Darboux;
class DraftTrihedron;
HArray1OfReal from TColStd,
SequenceOfReal from TColStd,
HArray1OfVec from TColgp,
- SequenceOfVec from TColgp
+ SequenceOfVec from TColgp,
+ Trihedron from GeomFill
raises
OutOfRange, ConstructionError
Create returns CorrectedFrenet from GeomFill;
+ Create (ForEvaluation: Boolean)
+ returns CorrectedFrenet from GeomFill;
+
Copy(me)
returns TrihedronLaw from GeomFill
is redefined;
- Init(me: mutable)
+ Init(me: mutable)
is static private;
InitInterval(me; First, Last, Step: Real;
SeqPoles: out SequenceOfReal from TColStd;
SeqAngle: out SequenceOfReal from TColStd;
SeqTangent: out SequenceOfVec from TColgp;
- SeqNormal: out SequenceOfVec from TColgp)
+ SeqNormal: out SequenceOfVec from TColgp)
returns Boolean
--- Purpose: Computes BSpline representation of Normal evolution at one
--- interval of continuity of Frenet. Returns True if FuncInt = 0
OutOfRange from Standard
is redefined;
+
+-- =================== To define the best trihedron mode ===============
+
+ EvaluateBestMode(me : mutable)
+ returns Trihedron from GeomFill;
+ ---Purpose: Tries to define the best trihedron mode
+ -- for the curve. It can be:
+ -- - Frenet
+ -- - CorrectedFrenet
+ -- - DiscreteTrihedron
+ -- Warning: the CorrectedFrenet must be constructed
+ -- with option ForEvaluation = True,
+ -- the curve must be set by method SetCurve.
+
-- =================== To help computation of Tolerance ===============
GetAverageLaw(me : mutable;
is redefined;
fields
- frenet : Frenet from GeomFill;
- EvolAroundT : Function from Law;
- TLaw : Function from Law;
- AT, AN : Vec from gp;
- isFrenet : Boolean;
+ frenet : Frenet from GeomFill;
+ EvolAroundT : Function from Law;
+ TLaw : Function from Law;
+ AT, AN : Vec from gp;
+ isFrenet : Boolean;
+ myForEvaluation : Boolean;
+
---OCC78
HArrPoles : HArray1OfReal from TColStd;
HArrAngle : HArray1OfReal from TColStd;
#include <Geom_BSplineCurve.hxx>
#include <TColgp_HArray1OfPnt.hxx>
+
#ifdef DEB
static Standard_Boolean Affich=0;
#endif
}
#endif
+
+static Standard_Real ComputeTorsion(const Standard_Real Param,
+ const Handle(Adaptor3d_HCurve)& aCurve)
+{
+ Standard_Real Torsion;
+
+ gp_Pnt aPoint;
+ gp_Vec DC1, DC2, DC3;
+ aCurve->D3(Param, aPoint, DC1, DC2, DC3);
+ gp_Vec DC1crossDC2 = DC1 ^ DC2;
+ Standard_Real Norm_DC1crossDC2 = DC1crossDC2.Magnitude();
+
+ Standard_Real DC1DC2DC3 = DC1crossDC2 * DC3 ; //mixed product
+
+ Standard_Real Tol = gp::Resolution();
+ Standard_Real SquareNorm_DC1crossDC2 = Norm_DC1crossDC2 * Norm_DC1crossDC2;
+ if (SquareNorm_DC1crossDC2 <= Tol)
+ Torsion = 0.;
+ else
+ Torsion = DC1DC2DC3 / SquareNorm_DC1crossDC2 ;
+
+ return Torsion;
+}
+
//===============================================================
// Function : smoothlaw
// Purpose : to smooth a law : Reduce the number of knots
}
//===============================================================
-// Function :
+// Function : Constructor
// Purpose :
//===============================================================
GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet()
: isFrenet(Standard_False)
{
frenet = new GeomFill_Frenet();
+ myForEvaluation = Standard_False;
+}
+
+//===============================================================
+// Function : Constructor
+// Purpose :
+//===============================================================
+GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet(const Standard_Boolean ForEvaluation)
+ : isFrenet(Standard_False)
+{
+ frenet = new GeomFill_Frenet();
+ myForEvaluation = ForEvaluation;
}
Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
{
// No probleme isFrenet
isFrenet = Standard_True;
+ break;
}
default :
{
for(i = 1; i <= NbI; i++) {
NbStep = Max(Standard_Integer((T(i+1) - T(i))/AvStep), 3);
Step = (T(i+1) - T(i))/NbStep;
- if(!InitInterval(T(i), T(i+1), Step, StartAng, Tangent, Normal, AT, AN, Func, SeqPoles, SeqAngle, SeqTangent, SeqNormal))
- if(isFrenet) isFrenet = Standard_False;
+ if(!InitInterval(T(i), T(i+1), Step, StartAng, Tangent, Normal, AT, AN, Func,
+ SeqPoles, SeqAngle, SeqTangent, SeqNormal))
+ {
+ if(isFrenet)
+ isFrenet = Standard_False;
+ }
Handle(Law_Composite)::DownCast(EvolAroundT)->ChangeLaws().Append(Func);
}
if(myTrimmed->IsPeriodic())
HArrTangent->ChangeValue(i) = SeqTangent(i);
HArrNormal->ChangeValue(i) = SeqNormal(i);
};
-
+
#if DRAW
if (Affich) {
draw(EvolAroundT);
TColStd_SequenceOfReal EvolAT;
Standard_Real Param = First, LengthMin, L, norm;
Standard_Boolean isZero = Standard_True, isConst = Standard_True;
+ const Standard_Real minnorm = 1.e-16;
Standard_Integer i;
gp_Pnt PonC;
gp_Vec D1;
Standard_Real angleAT, currParam, currStep = Step;
Handle( Geom_Plane ) aPlane;
- Standard_Boolean isPlanar = FindPlane( myCurve, aPlane );
+ Standard_Boolean isPlanar = Standard_False;
+ if (!myForEvaluation)
+ isPlanar = FindPlane( myCurve, aPlane );
i = 1;
currParam = Param;
//Evaluate the Next step
CS.D1(Param, PonC, D1);
- L = Max(PonC.XYZ().Modulus()/2, LengthMin);
+
+ L = PonC.XYZ().Modulus()/2;
norm = D1.Magnitude();
- if (norm < Precision::Confusion()) {
- norm = Precision::Confusion();
+ if (norm <= gp::Resolution())
+ {
+ //norm = 2.*gp::Resolution();
+ norm = minnorm;
}
currStep = L / norm;
- if (currStep > Step) currStep = Step;//default value
+ if (currStep <= gp::Resolution()) //L = 0 => curvature = 0, linear segment
+ currStep = Step;
+ if (currStep < Precision::Confusion()) //too small step
+ currStep = Precision::Confusion();
+ if (currStep > Step) //too big step
+ currStep = Step;//default value
}
else
currStep /= 2; // Step too long !
Precision::PConfusion()/2);
}
+//===============================================================
+// Function : EvaluateBestMode
+// Purpose :
+//===============================================================
+GeomFill_Trihedron GeomFill_CorrectedFrenet::EvaluateBestMode()
+{
+ if (EvolAroundT.IsNull())
+ return GeomFill_IsFrenet; //Frenet
+
+ const Standard_Real MaxAngle = 3.*M_PI/4.;
+ const Standard_Real MaxTorsion = 100.;
+
+ Standard_Real Step, u, v, tmin, tmax;
+ Standard_Integer NbInt, i, j, k = 1;
+ NbInt = EvolAroundT->NbIntervals(GeomAbs_CN);
+ TColStd_Array1OfReal Int(1, NbInt+1);
+ EvolAroundT->Intervals(Int, GeomAbs_CN);
+ gp_Pnt2d old;
+ gp_Vec2d aVec, PrevVec;
+
+ Standard_Integer NbSamples = 10;
+ for(i = 1; i <= NbInt; i++){
+ tmin = Int(i);
+ tmax = Int(i+1);
+ Standard_Real Torsion = ComputeTorsion(tmin, myTrimmed);
+ if (Abs(Torsion) > MaxTorsion)
+ return GeomFill_IsDiscreteTrihedron; //DiscreteTrihedron
+
+ Handle(Law_Function) trimmedlaw = EvolAroundT->Trim(tmin, tmax, Precision::PConfusion()/2);
+ Step = (Int(i+1)-Int(i))/NbSamples;
+ for (j = 0; j <= NbSamples; j++) {
+ u = tmin + j*Step;
+ v = trimmedlaw->Value(u);
+ gp_Pnt2d point2d(u,v);
+ if (j != 0)
+ {
+ aVec.SetXY(point2d.XY() - old.XY());
+ if (k > 2)
+ {
+ Standard_Real theAngle = PrevVec.Angle(aVec);
+ if (Abs(theAngle) > MaxAngle)
+ return GeomFill_IsDiscreteTrihedron; //DiscreteTrihedron
+ }
+ PrevVec = aVec;
+ }
+ old = point2d;
+ k++;
+ }
+ }
+
+ return GeomFill_IsCorrectedFrenet; //CorrectedFrenet
+}
+
//===============================================================
// Function : GetAverageLaw
// Purpose :
--- /dev/null
+-- Created on: 2013-02-05
+-- Created by: Julia GERASIMOVA
+-- Copyright (c) 2001-2013 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.
+--
+-- 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.
+--
+-- 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.
+
+
+class DiscreteTrihedron from GeomFill
+ inherits TrihedronLaw from GeomFill
+
+ ---Purpose: Defined Discrete Trihedron Law.
+ -- The requirement for path curve is only G1.
+ -- The result is C0-continuous surface
+ -- that can be later approximated to C1.
+
+uses
+ HCurve from Adaptor3d,
+ Shape from GeomAbs,
+ Pnt from gp,
+ Vec from gp,
+ Array1OfReal from TColStd,
+ Frenet from GeomFill,
+ HSequenceOfAx2 from GeomFill,
+ HSequenceOfReal from TColStd
+
+raises
+ OutOfRange, ConstructionError
+is
+
+ Create
+ returns DiscreteTrihedron from GeomFill
+ raises ConstructionError;
+
+ Copy(me)
+ returns TrihedronLaw from GeomFill
+ is redefined;
+
+ Init(me: mutable)
+ is static;
+
+ SetCurve(me : mutable; C : HCurve from Adaptor3d)
+ is redefined;
+
+--
+--
+--========== To compute Location and derivatives Location
+--
+ D0(me : mutable;
+ Param: Real;
+ Tangent : out Vec from gp;
+ Normal : out Vec from gp;
+ BiNormal : out Vec from gp)
+ ---Purpose: compute Trihedron on curve at parameter <Param>
+ returns Boolean is redefined;
+
+ D1(me : mutable;
+ Param: Real;
+ Tangent : out Vec from gp;
+ DTangent : out Vec from gp;
+ Normal : out Vec from gp;
+ DNormal : out Vec from gp;
+ BiNormal : out Vec from gp;
+ DBiNormal : out Vec from gp)
+ ---Purpose: compute Trihedron and derivative Trihedron on curve
+ -- at parameter <Param>
+ -- Warning : It used only for C1 or C2 aproximation
+ -- For the moment it returns null values for DTangent, DNormal
+ -- and DBiNormal.
+ returns Boolean
+ is redefined;
+
+ D2(me : mutable;
+ Param: Real;
+ Tangent : out Vec from gp;
+ DTangent : out Vec from gp;
+ D2Tangent : out Vec from gp;
+ Normal : out Vec from gp;
+ DNormal : out Vec from gp;
+ D2Normal : out Vec from gp;
+ BiNormal : out Vec from gp;
+ DBiNormal : out Vec from gp;
+ D2BiNormal : out Vec from gp)
+ ---Purpose: compute Trihedron on curve
+ -- first and seconde derivatives.
+ -- Warning : It used only for C2 aproximation
+ -- For the moment it returns null values for DTangent, DNormal
+ -- DBiNormal, D2Tangent, D2Normal, D2BiNormal.
+ returns Boolean
+ is redefined;
+--
+-- =================== Management of continuity ===================
+--
+ NbIntervals(me; S : Shape from GeomAbs)
+ ---Purpose: Returns the number of intervals for continuity
+ -- <S>.
+ -- May be one if Continuity(me) >= <S>
+ returns Integer is redefined;
+
+ Intervals(me; T : in out Array1OfReal from TColStd;
+ S : Shape from GeomAbs)
+ ---Purpose: Stores in <T> the parameters bounding the intervals
+ -- of continuity <S>.
+ --
+ -- The array must provide enough room to accomodate
+ -- for the parameters. i.e. T.Length() > NbIntervals()
+ raises
+ OutOfRange from Standard
+ is redefined;
+
+
+-- =================== To help computation of Tolerance ===============
+ GetAverageLaw(me : mutable;
+ ATangent : out Vec from gp;
+ ANormal : out Vec from gp;
+ ABiNormal : out Vec from gp)
+ ---Purpose: Get average value of Tangent(t) and Normal(t) it is usful to
+ -- make fast approximation of rational surfaces.
+ is redefined;
+
+-- =================== To help Particular case ===============
+
+ IsConstant(me)
+ ---Purpose: Say if the law is Constant.
+ returns Boolean
+ is redefined;
+
+ IsOnlyBy3dCurve(me)
+ ---Purpose: Return True.
+ returns Boolean
+ is redefined;
+
+
+fields
+
+ myPoint : Pnt from gp;
+ myTrihedrons : HSequenceOfAx2 from GeomFill;
+ myKnots : HSequenceOfReal from TColStd;
+ myFrenet : Frenet from GeomFill;
+ myUseFrenet : Boolean from Standard;
+
+end DiscreteTrihedron;
--- /dev/null
+// Created on: 2013-02-05
+// Created by: Julia GERASIMOVA
+// Copyright (c) 2001-2013 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.
+//
+// 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.
+//
+// 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.
+
+
+#include <GeomFill_DiscreteTrihedron.ixx>
+#include <GeomFill_DiscreteTrihedron.hxx>
+#include <GeomFill_Frenet.hxx>
+#include <GeomAbs_CurveType.hxx>
+#include <Adaptor3d_HCurve.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_HSequenceOfReal.hxx>
+#include <GeomFill_HSequenceOfAx2.hxx>
+
+
+static const Standard_Real TolConf = Precision::Confusion();
+
+//=======================================================================
+//function : GeomFill_DiscreteTrihedron
+//purpose : Constructor
+//=======================================================================
+
+GeomFill_DiscreteTrihedron::GeomFill_DiscreteTrihedron()
+{
+ myFrenet = new GeomFill_Frenet();
+ myKnots = new TColStd_HSequenceOfReal();
+ myTrihedrons = new GeomFill_HSequenceOfAx2();
+}
+
+//=======================================================================
+//function : Copy
+//purpose :
+//=======================================================================
+
+Handle(GeomFill_TrihedronLaw) GeomFill_DiscreteTrihedron::Copy() const
+{
+ Handle(GeomFill_DiscreteTrihedron) copy = new (GeomFill_DiscreteTrihedron)();
+ if (!myCurve.IsNull()) copy->SetCurve(myCurve);
+ return copy;
+}
+
+//=======================================================================
+//function : SetCurve
+//purpose :
+//=======================================================================
+
+void GeomFill_DiscreteTrihedron::SetCurve(const Handle(Adaptor3d_HCurve)& C)
+{
+ GeomFill_TrihedronLaw::SetCurve(C);
+ if (! C.IsNull()) {
+ GeomAbs_CurveType type;
+ type = C->GetType();
+ switch (type) {
+ case GeomAbs_Circle:
+ case GeomAbs_Ellipse:
+ case GeomAbs_Hyperbola:
+ case GeomAbs_Parabola:
+ case GeomAbs_Line:
+ {
+ // No probleme
+ myUseFrenet = Standard_True;
+ myFrenet->SetCurve(C);
+ break;
+ }
+ default :
+ {
+ myUseFrenet = Standard_False;
+ // We have to fill <myKnots> and <myTrihedrons>
+ Init();
+ break;
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : Init
+//purpose :
+//=======================================================================
+
+void GeomFill_DiscreteTrihedron::Init()
+{
+ Standard_Integer NbIntervals = myTrimmed->NbIntervals(GeomAbs_CN);
+ TColStd_Array1OfReal Knots(1, NbIntervals+1);
+ myTrimmed->Intervals(Knots, GeomAbs_CN);
+
+ //Standard_Real Tol = Precision::Confusion();
+ Standard_Integer NbSamples = 10;
+
+ Standard_Integer i, j;
+ for (i = 1; i <= NbIntervals; i++)
+ {
+ Standard_Real delta = (Knots(i+1) - Knots(i))/NbSamples;
+ for (j = 0; j < NbSamples; j++)
+ {
+ Standard_Real Param = Knots(i) + j*delta;
+ myKnots->Append(Param);
+ }
+ }
+ myKnots->Append(Knots(NbIntervals+1));
+
+
+ gp_Pnt Origin(0.,0.,0.), Pnt, SubPnt;
+ gp_Vec Tangent;
+ gp_Dir TangDir;
+ Standard_Real norm;
+ for (i = 1; i <= myKnots->Length(); i++)
+ {
+ Standard_Real Param = myKnots->Value(i);
+ myTrimmed->D1(Param, Pnt, Tangent);
+ norm = Tangent.Magnitude();
+ if (norm < TolConf)
+ {
+ Standard_Real subdelta = (myKnots->Value(i+1) - myKnots->Value(i))/NbSamples;
+ if (subdelta < Precision::PConfusion())
+ subdelta = myKnots->Value(i+1) - myKnots->Value(i);
+ SubPnt = myTrimmed->Value(Param + subdelta);
+ Tangent.SetXYZ(SubPnt.XYZ() - Pnt.XYZ());
+ }
+ //Tangent.Normalize();
+ TangDir = Tangent; //normalize;
+ Tangent = TangDir;
+ if (i == 1) //first point
+ {
+ gp_Ax2 FirstAxis(Origin, TangDir);
+ myTrihedrons->Append(FirstAxis);
+ }
+ else
+ {
+ gp_Ax2 LastAxis = myTrihedrons->Value(myTrihedrons->Length());
+ gp_Vec LastTangent = LastAxis.Direction();
+ gp_Vec AxisOfRotation = LastTangent ^ Tangent;
+ if (AxisOfRotation.Magnitude() <= gp::Resolution()) //tangents are equal or opposite
+ {
+ Standard_Real ScalarProduct = LastTangent * Tangent;
+ if (ScalarProduct > 0.) //tangents are equal
+ myTrihedrons->Append(LastAxis);
+ else //tangents are opposite
+ {
+ Standard_Real NewParam = (myKnots->Value(i-1) + myKnots->Value(i))/2.;
+ if (NewParam - myKnots->Value(i-1) < gp::Resolution())
+ Standard_ConstructionError::Raise("GeomFill_DiscreteTrihedron : impassable singularities on path curve");
+ myKnots->InsertBefore(i, NewParam);
+ i--;
+ }
+ }
+ else //good value of angle
+ {
+ Standard_Real theAngle = LastTangent.AngleWithRef(Tangent, AxisOfRotation);
+ gp_Ax1 theAxisOfRotation(Origin, AxisOfRotation);
+ gp_Ax2 NewAxis = LastAxis.Rotated(theAxisOfRotation, theAngle);
+ NewAxis.SetDirection(TangDir); //to prevent accumulation of floating computations error
+ myTrihedrons->Append(NewAxis);
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : D0
+//purpose :
+//=======================================================================
+
+Standard_Boolean GeomFill_DiscreteTrihedron::D0(const Standard_Real Param,
+ gp_Vec& Tangent,
+ gp_Vec& Normal,
+ gp_Vec& BiNormal)
+{
+ if (myUseFrenet)
+ {
+ myFrenet->D0(Param, Tangent, Normal, BiNormal);
+ }
+ else
+ {
+ //Locate <Param> in the sequence <myKnots>
+ Standard_Integer Index = -1;
+ Standard_Real TolPar = Precision::PConfusion();
+ //Standard_Real TolConf = Precision::Confusion();
+ Standard_Integer NbSamples = 10;
+ gp_Pnt Origin(0.,0.,0.);
+
+ Standard_Integer i;
+ //gp_Ax2 PrevAxis;
+ //Standard_Real PrevParam;
+
+ Standard_Integer I1, I2;
+ I1 = 1;
+ I2 = myKnots->Length();
+ for (;;)
+ {
+ i = (I1 + I2)/2;
+ if (Param <= myKnots->Value(i))
+ I2 = i;
+ else
+ I1 = i;
+ if (I2 - I1 <= 1)
+ break;
+ }
+ Index = I1;
+ if (Abs(Param - myKnots->Value(I2)) < TolPar)
+ Index = I2;
+
+ Standard_Real PrevParam = myKnots->Value(Index);
+ gp_Ax2 PrevAxis = myTrihedrons->Value(Index);
+ gp_Ax2 theAxis;
+ if (Abs(Param - PrevParam) < TolPar)
+ theAxis = PrevAxis;
+ else //<Param> is between knots
+ {
+ myTrimmed->D1(Param, myPoint, Tangent);
+ Standard_Real norm = Tangent.Magnitude();
+ if (norm < TolConf)
+ {
+ Standard_Real subdelta = (myKnots->Value(Index+1) - Param)/NbSamples;
+ if (subdelta < Precision::PConfusion())
+ subdelta = myKnots->Value(Index+1) - Param;
+ gp_Pnt SubPnt = myTrimmed->Value(Param + subdelta);
+ Tangent.SetXYZ(SubPnt.XYZ() - myPoint.XYZ());
+ }
+ //Tangent.Normalize();
+ gp_Dir TangDir(Tangent); //normalize;
+ Tangent = TangDir;
+ gp_Vec PrevTangent = PrevAxis.Direction();
+ gp_Vec AxisOfRotation = PrevTangent ^ Tangent;
+ if (AxisOfRotation.Magnitude() <= gp::Resolution()) //tangents are equal
+ {
+ //we assume that tangents can not be opposite
+ theAxis = PrevAxis;
+ }
+ else //good value of angle
+ {
+ Standard_Real theAngle = PrevTangent.AngleWithRef(Tangent, AxisOfRotation);
+ gp_Ax1 theAxisOfRotation(Origin, AxisOfRotation);
+ theAxis = PrevAxis.Rotated(theAxisOfRotation, theAngle);
+ }
+ theAxis.SetDirection(TangDir); //to prevent accumulation of floating computations error
+ } //end of else (Param is between knots)
+
+ Tangent = theAxis.Direction();
+ Normal = theAxis.XDirection();
+ BiNormal = theAxis.YDirection();
+ }
+ return Standard_True;
+}
+
+//=======================================================================
+//function : D1
+//purpose :
+//=======================================================================
+
+Standard_Boolean GeomFill_DiscreteTrihedron::D1(const Standard_Real Param,
+ gp_Vec& Tangent,
+ gp_Vec& DTangent,
+ gp_Vec& Normal,
+ gp_Vec& DNormal,
+ gp_Vec& BiNormal,
+ gp_Vec& DBiNormal)
+{
+ if (myUseFrenet)
+ {
+ myFrenet->D1(Param, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal);
+ }
+ else
+ {
+ D0(Param, Tangent, Normal, BiNormal);
+
+ DTangent.SetCoord(0.,0.,0.);
+ DNormal.SetCoord(0.,0.,0.);
+ DBiNormal.SetCoord(0.,0.,0.);
+ }
+ return Standard_True;
+}
+
+//=======================================================================
+//function : D2
+//purpose :
+//=======================================================================
+
+Standard_Boolean GeomFill_DiscreteTrihedron::D2(const Standard_Real Param,
+ gp_Vec& Tangent,
+ gp_Vec& DTangent,
+ gp_Vec& D2Tangent,
+ gp_Vec& Normal,
+ gp_Vec& DNormal,
+ gp_Vec& D2Normal,
+ gp_Vec& BiNormal,
+ gp_Vec& DBiNormal,
+ gp_Vec& D2BiNormal)
+{
+ if (myUseFrenet)
+ {
+ myFrenet->D2(Param, Tangent, DTangent, D2Tangent,
+ Normal, DNormal, D2Normal,
+ BiNormal, DBiNormal, D2BiNormal);
+ }
+ else
+ {
+ D0(Param, Tangent, Normal, BiNormal);
+
+ DTangent.SetCoord(0.,0.,0.);
+ DNormal.SetCoord(0.,0.,0.);
+ DBiNormal.SetCoord(0.,0.,0.);
+ D2Tangent.SetCoord(0.,0.,0.);
+ D2Normal.SetCoord(0.,0.,0.);
+ D2BiNormal.SetCoord(0.,0.,0.);
+ }
+ return Standard_True;
+}
+
+//=======================================================================
+//function : NbIntervals
+//purpose :
+//=======================================================================
+
+Standard_Integer GeomFill_DiscreteTrihedron::NbIntervals(const GeomAbs_Shape S) const
+{
+ return (myTrimmed->NbIntervals(GeomAbs_CN));
+}
+
+//=======================================================================
+//function : Intervals
+//purpose :
+//=======================================================================
+
+void GeomFill_DiscreteTrihedron::Intervals(TColStd_Array1OfReal& T,
+ const GeomAbs_Shape S) const
+{
+ myTrimmed->Intervals(T, GeomAbs_CN);
+}
+
+ void GeomFill_DiscreteTrihedron::GetAverageLaw(gp_Vec& ATangent,
+ gp_Vec& ANormal,
+ gp_Vec& ABiNormal)
+{
+ Standard_Integer Num = 20; //order of digitalization
+ gp_Vec T, N, BN;
+ ATangent = gp_Vec(0, 0, 0);
+ ANormal = gp_Vec(0, 0, 0);
+ ABiNormal = gp_Vec(0, 0, 0);
+ Standard_Real Step = (myTrimmed->LastParameter() -
+ myTrimmed->FirstParameter()) / Num;
+ Standard_Real Param;
+ for (Standard_Integer i = 0; i <= Num; i++) {
+ Param = myTrimmed->FirstParameter() + i*Step;
+ if (Param > myTrimmed->LastParameter()) Param = myTrimmed->LastParameter();
+ D0(Param, T, N, BN);
+ ATangent += T;
+ ANormal += N;
+ ABiNormal += BN;
+ }
+ ATangent /= Num + 1;
+ ANormal /= Num + 1;
+
+ ATangent.Normalize();
+ ABiNormal = ATangent.Crossed(ANormal).Normalized();
+ ANormal = ABiNormal.Crossed(ATangent);
+}
+
+//=======================================================================
+//function : IsConstant
+//purpose :
+//=======================================================================
+
+ Standard_Boolean GeomFill_DiscreteTrihedron::IsConstant() const
+{
+ return (myCurve->GetType() == GeomAbs_Line);
+}
+
+//=======================================================================
+//function : IsOnlyBy3dCurve
+//purpose :
+//=======================================================================
+
+ Standard_Boolean GeomFill_DiscreteTrihedron::IsOnlyBy3dCurve() const
+{
+ return Standard_True;
+}
DoSingular(me: mutable; U: Real; Index: Integer;
Tangent, BiNormal: out Vec from gp;
- n, k, TFlag, BNFlag: out Integer)
+ n, k, TFlag, BNFlag: out Integer;
+ Delta: out Real)
returns Boolean
is private;
Param: Real; Index: Integer;
Tangent : out Vec from gp;
Normal : out Vec from gp;
- BiNormal : out Vec from gp)
+ BiNormal : out Vec from gp;
+ Delta : out Real)
---Purpose: computes Triedrhon on curve at parameter <Param>
returns Boolean
is private;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
- DBiNormal : out Vec from gp)
+ DBiNormal : out Vec from gp;
+ Delta : out Real)
---Purpose: computes Triedrhon and derivative Trihedron on curve
-- at parameter <Param>
-- Warning : It used only for C1 or C2 aproximation
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
- D2BiNormal : out Vec from gp)
+ D2BiNormal : out Vec from gp;
+ Delta : out Real)
---Purpose: computes Trihedron on curve
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
{
Standard_Real norm;
Standard_Integer Index;
+ Standard_Real Delta = 0.;
if(IsSingular(Param, Index))
- if (SingularD0(Param, Index, Tangent, Normal, BiNormal))
+ if (SingularD0(Param, Index, Tangent, Normal, BiNormal, Delta))
return Standard_True;
- myTrimmed->D2(Param, P, Tangent, BiNormal);
+ Standard_Real theParam = Param + Delta;
+ myTrimmed->D2(theParam, P, Tangent, BiNormal);
Tangent.Normalize();
BiNormal = Tangent.Crossed(BiNormal);
norm = BiNormal.Magnitude();
gp_Vec& DBiNormal)
{
Standard_Integer Index;
+ Standard_Real Delta = 0.;
if(IsSingular(Param, Index))
- if (SingularD1(Param, Index, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal))
+ if (SingularD1(Param, Index, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal, Delta))
return Standard_True;
// Standard_Real Norma;
+ Standard_Real theParam = Param + Delta;
gp_Vec DC1, DC2, DC3;
- myTrimmed->D3(Param, P, DC1, DC2, DC3);
+ myTrimmed->D3(theParam, P, DC1, DC2, DC3);
Tangent = DC1.Normalized();
//if (DC2.Magnitude() <= NullTol || Tangent.Crossed(DC2).Magnitude() <= NullTol) {
gp_Vec& D2BiNormal)
{
Standard_Integer Index;
+ Standard_Real Delta = 0.;
if(IsSingular(Param, Index))
if(SingularD2(Param, Index, Tangent, DTangent, D2Tangent,
Normal, DNormal, D2Normal,
- BiNormal, DBiNormal, D2BiNormal))
+ BiNormal, DBiNormal, D2BiNormal,
+ Delta))
return Standard_True;
// Standard_Real Norma;
+ Standard_Real theParam = Param + Delta;
gp_Vec DC1, DC2, DC3, DC4;
- myTrimmed->D3(Param, P, DC1, DC2, DC3);
- DC4 = myTrimmed->DN(Param, 4);
+ myTrimmed->D3(theParam, P, DC1, DC2, DC3);
+ DC4 = myTrimmed->DN(theParam, 4);
Tangent = DC1.Normalized();
Standard_Integer& n,
Standard_Integer& k,
Standard_Integer& TFlag,
- Standard_Integer& BNFlag)
+ Standard_Integer& BNFlag,
+ Standard_Real& Delta)
{
Standard_Integer i, MaxN = 20;
+ Delta = 0.;
Standard_Real h;
h = 2*mySnglLen->Value(Index);
TFlag = 1;
BNFlag = 1;
GetInterval(A, B);
- if (U >= (A + B)/2) h = -h;
+ if (U >= (A + B)/2)
+ h = -h;
for(i = 1; i <= MaxN; i++) {
Tangent = myTrimmed->DN(U, i);
if(Tangent.Magnitude() > Precision::Confusion()) break;
break;
}
}
- if (i > MaxN) return Standard_False;
+ if (i > MaxN)
+ {
+ Delta = h;
+ return Standard_False;
+ }
+
BiNormal.Normalize();
k = i;
const Standard_Integer Index,
gp_Vec& Tangent,
gp_Vec& Normal,
- gp_Vec& BiNormal)
+ gp_Vec& BiNormal,
+ Standard_Real& Delta)
{
Standard_Integer n, k, TFlag, BNFlag;
if(!DoSingular(Param, Index, Tangent, BiNormal,
- n, k, TFlag, BNFlag)) return Standard_False;
+ n, k, TFlag, BNFlag, Delta))
+ return Standard_False;
+
Tangent *= TFlag;
BiNormal *= BNFlag;
Normal = BiNormal;
const Standard_Integer Index,
gp_Vec& Tangent,gp_Vec& DTangent,
gp_Vec& Normal,gp_Vec& DNormal,
- gp_Vec& BiNormal,gp_Vec& DBiNormal)
+ gp_Vec& BiNormal,gp_Vec& DBiNormal,
+ Standard_Real& Delta)
{
Standard_Integer n, k, TFlag, BNFlag;
- if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag)) return Standard_False;
+ if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag, Delta))
+ return Standard_False;
gp_Vec F, DF, Dtmp;
F = myTrimmed->DN(Param, n);
gp_Vec& D2Normal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal,
- gp_Vec& D2BiNormal)
+ gp_Vec& D2BiNormal,
+ Standard_Real& Delta)
{
Standard_Integer n, k, TFlag, BNFlag;
- if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag))
+ if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag, Delta))
return Standard_False;
gp_Vec F, DF, D2F, Dtmp1, Dtmp2;
-- beetween tangents on the section law and
-- tangent of iso-v on approximed surface
-
+ SetForceApproxC1(me : in out;
+ ForceApproxC1 : Boolean from Standard);
+ ---Purpose: Set the flag that indicates attempt to approximate
+ -- a C1-continuous surface if a swept surface proved
+ -- to be C0.
+
ExchangeUV(me)
---Purpose: returns true if sections are U-Iso
-- This can be produce in some cases when <WithKpart> is True.
First, Last : Real;
SFirst, SLast: Real;
Tol3d, BoundTol, Tol2d, TolAngular : Real;
- SError : Real;
-
+ SError : Real;
+ myForceApproxC1 : Boolean;
+
myLoc : LocationLaw from GeomFill;
mySec : SectionLaw from GeomFill;
mySurface : Surface from Geom;
#include <Approx_SweepApproximation.hxx>
#include <AdvApprox_PrefAndRec.hxx>
#include <AdvApprox_ApproxAFunction.hxx>
+#include <GeomConvert_ApproxSurface.hxx>
#include <Precision.hxx>
#include <ElCLib.hxx>
myLoc = Location;
myKPart = WithKpart;
SetTolerance(1.e-4);
+ myForceApproxC1 = Standard_False;
myLoc->GetDomain(First, Last);
SFirst = SLast = 30.081996;
TolAngular = ToleranceAngular;
}
+//=======================================================================
+//Function : SetForceApproxC1
+//Purpose : Set the flag that indicates attempt to approximate
+// a C1-continuous surface if a swept surface proved
+// to be C0.
+//=======================================================================
+ void GeomFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
+{
+ myForceApproxC1 = ForceApproxC1;
+}
+
+
//===============================================================
// Function : ExchangeUV
// Purpose :
Approx.UDegree(), Approx.VDegree(),
mySec->IsUPeriodic());
SError = Approx. MaxErrorOnSurf();
-
- // Les Courbes 2d
- myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber());
- CError = new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber());
- Standard_Integer kk,ii, ifin = 1, ideb;
-
- if (myLoc->HasFirstRestriction()) {
- ideb = 1;
- }
- else {
- ideb = 2;
- }
- ifin += myLoc->TraceNumber();
- if (myLoc->HasLastRestriction()) ifin++;
-
- for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) {
- Handle(Geom2d_BSplineCurve) C
- = new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk),
- Approx.Curves2dKnots(),
- Approx.Curves2dMults(),
- Approx.Curves2dDegree());
- myCurve2d->SetValue(ii, C);
- CError->SetValue(1, ii, Approx.Max2dError(kk));
- CError->SetValue(2, ii, Approx.Max2dError(kk));
- }
- // Si les courbes de restriction, ne sont pas calcules, on prend
- // les iso Bords.
- if (! myLoc->HasFirstRestriction()) {
- gp_Dir2d D(0., 1.);
- gp_Pnt2d P(UKnots(UKnots.Lower()), 0);
- Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
- Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve)
- (LC, First, Last);
-
- myCurve2d->SetValue(1, TC);
- CError->SetValue(1, 1, 0.);
- CError->SetValue(2, 1, 0.);
- }
+ if (myForceApproxC1 && !mySurface->IsCNv(1))
+ {
+ Standard_Real theTol = 1.e-4;
+ GeomAbs_Shape theUCont = GeomAbs_C1, theVCont = GeomAbs_C1;
+ Standard_Integer degU = 14, degV = 14;
+ Standard_Integer nmax = 16;
+ Standard_Integer thePrec = 1;
+
+ GeomConvert_ApproxSurface ConvertApprox(mySurface,theTol,theUCont,theVCont,
+ degU,degV,nmax,thePrec);
+ if (ConvertApprox.HasResult())
+ {
+ mySurface = ConvertApprox.Surface();
+ myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2);
+ CError = new (TColStd_HArray2OfReal) (1,2, 1,2);
+
+ const Handle(Geom_BSplineSurface)& BSplSurf =
+ Handle(Geom_BSplineSurface)::DownCast(mySurface);
+
+ gp_Dir2d D(0., 1.);
+ gp_Pnt2d P(BSplSurf->UKnot(1), 0);
+ Handle(Geom2d_Line) LC1 = new (Geom2d_Line) (P, D);
+ Handle(Geom2d_TrimmedCurve) TC1 =
+ new (Geom2d_TrimmedCurve) (LC1, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
+
+ myCurve2d->SetValue(1, TC1);
+ CError->SetValue(1, 1, 0.);
+ CError->SetValue(2, 1, 0.);
- if (! myLoc->HasLastRestriction()) {
- gp_Dir2d D(0., 1.);
- gp_Pnt2d P(UKnots(UKnots.Upper()), 0);
- Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
- Handle(Geom2d_TrimmedCurve) TC =
- new (Geom2d_TrimmedCurve) (LC, First, Last);
- myCurve2d->SetValue(myCurve2d->Length(), TC);
- CError->SetValue(1, myCurve2d->Length(), 0.);
- CError->SetValue(2, myCurve2d->Length(), 0.);
- }
+ P.SetCoord(BSplSurf->UKnot(BSplSurf->NbUKnots()), 0);
+ Handle(Geom2d_Line) LC2 = new (Geom2d_Line) (P, D);
+ Handle(Geom2d_TrimmedCurve) TC2 =
+ new (Geom2d_TrimmedCurve) (LC2, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
+
+ myCurve2d->SetValue(myCurve2d->Length(), TC2);
+ CError->SetValue(1, myCurve2d->Length(), 0.);
+ CError->SetValue(2, myCurve2d->Length(), 0.);
+
+ SError = theTol;
+ }
+ } //if (!mySurface->IsCNv(1))
+
+ // Les Courbes 2d
+ if (myCurve2d.IsNull())
+ {
+ myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber());
+ CError = new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber());
+ Standard_Integer kk,ii, ifin = 1, ideb;
+
+ if (myLoc->HasFirstRestriction()) {
+ ideb = 1;
+ }
+ else {
+ ideb = 2;
+ }
+ ifin += myLoc->TraceNumber();
+ if (myLoc->HasLastRestriction()) ifin++;
+
+ for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) {
+ Handle(Geom2d_BSplineCurve) C
+ = new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk),
+ Approx.Curves2dKnots(),
+ Approx.Curves2dMults(),
+ Approx.Curves2dDegree());
+ myCurve2d->SetValue(ii, C);
+ CError->SetValue(1, ii, Approx.Max2dError(kk));
+ CError->SetValue(2, ii, Approx.Max2dError(kk));
+ }
+
+ // Si les courbes de restriction, ne sont pas calcules, on prend
+ // les iso Bords.
+ if (! myLoc->HasFirstRestriction()) {
+ gp_Dir2d D(0., 1.);
+ gp_Pnt2d P(UKnots(UKnots.Lower()), 0);
+ Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
+ Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve)
+ (LC, First, Last);
+
+ myCurve2d->SetValue(1, TC);
+ CError->SetValue(1, 1, 0.);
+ CError->SetValue(2, 1, 0.);
+ }
+
+ if (! myLoc->HasLastRestriction()) {
+ gp_Dir2d D(0., 1.);
+ gp_Pnt2d P(UKnots(UKnots.Upper()), 0);
+ Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
+ Handle(Geom2d_TrimmedCurve) TC =
+ new (Geom2d_TrimmedCurve) (LC, First, Last);
+ myCurve2d->SetValue(myCurve2d->Length(), TC);
+ CError->SetValue(1, myCurve2d->Length(), 0.);
+ CError->SetValue(2, myCurve2d->Length(), 0.);
+ }
+ } //if (myCurve2d.IsNull())
}
return Ok;
}
--- /dev/null
+puts "============"
+puts "OCC23824"
+puts "============"
+puts ""
+#######################################################################
+# Bad results of sweep operation when a path curve has unpredictable torsion along its way.
+#######################################################################
+
+set BugNumber OCC23824
+
+restore [locate_data_file bug23824_AXE.brep] spine
+restore [locate_data_file bug23824_profil.brep] profile
+
+wire spine spine
+
+mksweep spine
+setsweep -DT
+addsweep profile
+buildsweep result
+
+set square 516.633
+
+set nb_v_good 8
+set nb_e_good 10
+set nb_w_good 3
+set nb_f_good 3
+set nb_sh_good 1
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 25
+
+set 2dviewer 1
--- /dev/null
+puts "============"
+puts "OCC23824"
+puts "============"
+puts ""
+#######################################################################
+# Bad results of sweep operation when a path curve has unpredictable torsion along its way.
+#######################################################################
+
+set BugNumber OCC23824
+
+restore [locate_data_file bug23824_Case1_Path.brep] spine
+restore [locate_data_file bug23824_Case1_Profile.brep] profile
+
+wire spine spine
+wire profile profile
+
+mksweep spine
+setsweep -DT
+addsweep profile
+buildsweep result
+
+set square 8997.97
+
+set nb_v_good 2
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 1
+set nb_sh_good 1
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 8
+
+set 2dviewer 1
--- /dev/null
+puts "============"
+puts "OCC23824"
+puts "============"
+puts ""
+#######################################################################
+# Bad results of sweep operation when a path curve has unpredictable torsion along its way.
+#######################################################################
+
+set BugNumber OCC23824
+
+restore [locate_data_file bug23824_Case2_Path.brep] spine
+restore [locate_data_file bug23824_Case2_Profile.brep] profile
+
+wire spine spine
+wire profile profile
+
+mksweep spine
+setsweep -DT
+addsweep profile
+
+buildsweep result
+
+set square 848.989
+
+set nb_v_good 2
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 1
+set nb_sh_good 1
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 8
+
+set 2dviewer 1
--- /dev/null
+puts "============"
+puts "OCC23824"
+puts "============"
+puts ""
+#######################################################################
+# Bad results of sweep operation when a path curve has unpredictable torsion along its way.
+#######################################################################
+
+set BugNumber OCC23824
+
+restore [locate_data_file bug23824_Case3_Path.brep] spine
+restore [locate_data_file bug23824_Case3_Profile.brep] profile
+
+wire profile profile
+explode spine
+wire spine spine_1
+
+mksweep spine
+setsweep -DT
+addsweep profile
+buildsweep result
+
+set square 38260.5
+
+set nb_v_good 2
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 1
+set nb_sh_good 1
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 8
+
+set 2dviewer 1