enumeration TransitionStyle
is Modified, Right, Round end;
+ enumeration TypeOfContact
+ is NoContact, Contact, ContactOnBorder end;
+
-- private class FilledPair;
---Purpose: A pair of bound shapes with the result.
Section from BRepFill,
Sweep from BRepFill,
DataMapOfShapeListOfShape from TopTools,
- SequenceOfSection from BRepFill
-
+ SequenceOfSection from BRepFill,
+ TypeOfContact from BRepFill
raises
DomainError from Standard,
Set(me : mutable;
AuxiliarySpine : Wire from TopoDS;
CurvilinearEquivalence : Boolean = Standard_True;
- KeepContact : Boolean = Standard_False );
+ KeepContact : TypeOfContact from BRepFill = BRepFill_NoContact );
---Purpose: Set an auxiliary spine to define the Normal
-- For each Point of the Spine P, an Point Q is evalued
param : out Real from Standard) is private;
ResetLoc(me : mutable) is private;
-
+
BuildHistory(me: mutable; theSweep: Sweep from BRepFill)
is private;
myForceApproxC1 : Boolean;
myLaw : Function from Law;
+ myIsAutomaticLaw : Boolean from Standard;
myLocation : LocationLaw from BRepFill;
mySection : SectionLaw from BRepFill;
myFaces : HArray2OfShape from TopTools;
#include <BRepBuilderAPI_Copy.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <IntCurveSurface_HInter.hxx>
+#include <IntCurveSurface_IntersectionPoint.hxx>
+#include <TColgp_HArray1OfPnt2d.hxx>
+#include <Law_Interpol.hxx>
+
#ifdef DRAW
#include <Draw.hxx>
#include <DrawTrSurf.hxx>
BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
: mySpine(Spine),
myForceApproxC1(Standard_False),
- myTrihedron(GeomFill_IsCorrectedFrenet),
+ myIsAutomaticLaw(Standard_False),
+ myTrihedron(GeomFill_IsCorrectedFrenet),
myTransition(BRepFill_Modified),
myStatus(GeomFill_PipeOk)
{
//=======================================================================
void BRepFill_PipeShell::Set(const TopoDS_Wire& AuxiliarySpine,
const Standard_Boolean CurvilinearEquivalence,
- const Standard_Boolean KeepContact)
+ const BRepFill_TypeOfContact KeepContact)
{
// Reorganization of the guide (pb of orientation and origin)
TopoDS_Wire TheGuide;
Standard_Boolean SpClose = mySpine.Closed(),
GuideClose = AuxiliarySpine.Closed();
+ if (KeepContact == BRepFill_ContactOnBorder)
+ myIsAutomaticLaw = Standard_True;
+
if (!SpClose && !GuideClose) {
// Case open reorientation of the guide
TopoDS_Wire sp = mySpine;
Guide->ChangeCurve().SetPeriodic(Standard_True);
if (CurvilinearEquivalence) { // trihedron by curvilinear reduced abscissa
- if (KeepContact)
+ if (KeepContact == BRepFill_Contact ||
+ KeepContact == BRepFill_ContactOnBorder)
myTrihedron = GeomFill_IsGuideACWithContact; // with rotation
else
myTrihedron = GeomFill_IsGuideAC; // without rotation
myLocation = new (BRepFill_ACRLaw) (mySpine, Loc);
}
else {// trihedron by plane
- if (KeepContact)
+ if (KeepContact == BRepFill_Contact ||
+ KeepContact == BRepFill_ContactOnBorder)
myTrihedron = GeomFill_IsGuidePlanWithContact; // with rotation
else
myTrihedron = GeomFill_IsGuidePlan; // without rotation
const Standard_Boolean WithCorrection)
{
Delete(Profile); // No duplication
- BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
- mySeq.Append(S);
- mySection.Nullify();
- ResetLoc();
+ if (myIsAutomaticLaw)
+ {
+ mySeq.Clear();
+ BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
+ S.Set(Standard_True);
+ mySeq.Append(S);
+ mySection.Nullify();
+ ResetLoc();
+
+ Handle(GeomFill_LocationGuide) Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(1));
+ Handle(TColgp_HArray1OfPnt2d) ParAndRad;
+ Loc->ComputeAutomaticLaw(ParAndRad);
+
+ //Compuite initial width of section (this will be 1.)
+ GProp_GProps GlobalProps;
+ BRepGProp::LinearProperties(Profile, GlobalProps);
+ gp_Pnt BaryCenter = GlobalProps.CentreOfMass();
+
+ TopoDS_Face ProfileFace = BRepLib_MakeFace(TopoDS::Wire(Profile), Standard_True); //only plane
+ Handle(Geom_Surface) thePlane = BRep_Tool::Surface(ProfileFace);
+ Handle(GeomAdaptor_HSurface) GAHplane = new GeomAdaptor_HSurface(thePlane);
+ IntCurveSurface_HInter Intersector;
+ Handle(Adaptor3d_HCurve) aHCurve [2];
+ aHCurve[0] = Loc->GetCurve();
+ aHCurve[1] = Loc->Guide();
+ gp_Pnt PointsOnSpines [2];
+ Standard_Integer i, j;
+
+ for (i = 0; i < 2; i++)
+ {
+ Intersector.Perform(aHCurve[i], GAHplane);
+ Standard_Real MinDist = RealLast();
+ for (j = 1; j <= Intersector.NbPoints(); j++)
+ {
+ gp_Pnt aPint = Intersector.Point(j).Pnt();
+ Standard_Real aDist = BaryCenter.Distance(aPint);
+ if (aDist < MinDist)
+ {
+ MinDist = aDist;
+ PointsOnSpines[i] = aPint;
+ }
+ }
+ }
+
+ //Correct <ParAndRad> according to <InitialWidth>
+ Standard_Real InitialWidth = PointsOnSpines[0].Distance(PointsOnSpines[1]);
+ Standard_Integer NbParRad = ParAndRad->Upper();
+ for (i = 1; i <= NbParRad; i++)
+ {
+ gp_Pnt2d aParRad = ParAndRad->Value(i);
+ aParRad.SetY( aParRad.Y() / InitialWidth );
+ ParAndRad->SetValue(i, aParRad);
+ }
+
+ myLaw = new Law_Interpol();
+
+ Standard_Boolean IsPeriodic =
+ (Abs(ParAndRad->Value(1).Y() - ParAndRad->Value(NbParRad).Y()) < Precision::Confusion());
+
+ (Handle(Law_Interpol)::DownCast(myLaw))->Set(ParAndRad->Array1(), IsPeriodic);
+ }
+ else
+ {
+ BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
+ mySeq.Append(S);
+ mySection.Nullify();
+ ResetLoc();
+ }
}
//=======================================================================
Vertex from TopoDS,
TransitionMode from BRepBuilderAPI,
PipeError from BRepBuilderAPI,
- PipeShell from BRepFill
+ PipeShell from BRepFill,
+ TypeOfContact from BRepFill
raises
DomainError from Standard,
SetMode(me : in out;
AuxiliarySpine : Wire from TopoDS;
CurvilinearEquivalence : Boolean;
- KeepContact : Boolean = Standard_False );
+ KeepContact : TypeOfContact from BRepFill = BRepFill_NoContact );
---Purpose: Sets an auxiliary spine to define the Normal
-- For each Point of the Spine P, an Point Q is evalued
is redefined;
fields
+
myPipe : PipeShell from BRepFill;
end MakePipeShell;
//purpose :
//=======================================================================
void BRepOffsetAPI_MakePipeShell::SetMode(const TopoDS_Wire& AuxiliarySpine,
- const Standard_Boolean CurvilinearEquivalence,
- const Standard_Boolean KeepContact)
+ const Standard_Boolean CurvilinearEquivalence,
+ const BRepFill_TypeOfContact KeepContact)
{
myPipe->Set(AuxiliarySpine, CurvilinearEquivalence, KeepContact);
}
#include <Geom_Circle.hxx>
#include <gp_Ax2.hxx>
+
//=======================================================================
// prism
//=======================================================================
di << " Surf have to be a shell or a face" <<"\n";
di << " -CN dx dy dz : BiNormal is given by dx dy dz" << "\n";
di << " -FX Tx Ty TZ [Nx Ny Nz] : Tangent and Normal are fixed" <<"\n";
- di << " -G guide 0|1(ACR|Plan) 0|1(contact|no contact) : with guide"<<"\n";
+ di << " -G guide 0|1(Plan|ACR) 0|1|2(no contact|contact|contact on border) : with guide"<<"\n";
return 0;
}
else
{
TopoDS_Shape Guide = DBRep::Get(a[2],TopAbs_WIRE);
- Sweep->SetMode(TopoDS::Wire(Guide), Draw::Atoi(a[3]), Draw::Atoi(a[4]));
+ Standard_Integer CurvilinearEquivalence = Draw::Atoi(a[3]);
+ Standard_Integer KeepContact = Draw::Atoi(a[4]);
+ Sweep->SetMode(TopoDS::Wire(Guide),
+ CurvilinearEquivalence,
+ (BRepFill_TypeOfContact)KeepContact);
}
}
Standard_Integer ii, L= nbreal/2;
TColgp_Array1OfPnt2d ParAndRad(1, L);
for (ii=1; ii<=L; ii++, cur+=2) {
- ParAndRad(ii).SetX(Draw::Atof(a[cur]));
- ParAndRad(ii).SetY(Draw::Atof(a[cur+1]));
- }
+ ParAndRad(ii).SetX(Draw::Atof(a[cur]));
+ ParAndRad(ii).SetY(Draw::Atof(a[cur+1]));
+ }
thelaw = new (Law_Interpol) ();
thelaw->Set(ParAndRad,
Abs(ParAndRad(1).Y() - ParAndRad(L).Y()) < Precision::Confusion());
gp_Vec To, B;
myTrimmed->D1(Param, P, To);//point et derivee au parametre Param sur myCurve
myTrimG->D0(tG, PG);// point au parametre tG sur myGuide
+ myCurPointOnGuide = PG;
gp_Vec n (P, PG); // vecteur definissant la normale
myTrimmed->D2(Param, P, To, DTo);
myTrimG->D1(tG, PG, TG);
+ myCurPointOnGuide = PG;
gp_Vec n (P, PG), dn;
Standard_Real Norm = n.Magnitude();
myTrimmed->D3(Param, P, To, DTo, D2To);
myTrimG->D2(tG, PG, TG, DTG);
+ myCurPointOnGuide = PG;
Standard_Real NTo = To.Magnitude();
Standard_Real N2To = To.SquareMagnitude();
Param2 : Real)
is static;
+ ComputeAutomaticLaw(me; ParAndRad : out HArray1OfPnt2d from TColgp)
+ returns PipeError from GeomFill;
fields
myLaw : TrihedronWithGuide from GeomFill; -- loi de triedre
#include <Adaptor3d_HSurface.hxx>
#include <IntCurveSurface_IntersectionPoint.hxx>
-#include <IntCurveSurface_HInter.hxx>
#include <Adaptor3d_Surface.hxx>
#include <GeomAdaptor.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColgp_HArray1OfPnt.hxx>
+#include <Extrema_ExtCS.hxx>
+#include <Extrema_POnSurf.hxx>
+
#if DRAW
static Standard_Integer Affich = 0;
#include <Approx_Curve3d.hxx>
Standard_Integer ii, Deg;
Standard_Boolean isconst, israt=Standard_False;
Standard_Real t, v,w, OldAngle=0, Angle, DeltaG, DeltaU, Diff;
- Standard_Real CurAngle = PrecAngle, a1, a2;
+ Standard_Real CurAngle = PrecAngle, a1/*, a2*/;
gp_Pnt2d p1,p2;
Handle(Geom_SurfaceOfRevolution) Revol; // surface de revolution
Handle(GeomAdaptor_HSurface) Pl; // = Revol
Handle(Geom_TrimmedCurve) S;
IntCurveSurface_IntersectionPoint PInt; // intersection guide/Revol
- IntCurveSurface_HInter Int;
Handle(TColStd_HArray1OfInteger) Mult;
Handle(TColStd_HArray1OfReal) Knots, Weights;
Handle(TColgp_HArray1OfPnt) Poles;
(Handle(Geom_Curve)::DownCast(mySection->Copy()), Uf, Ul);
}
S->Transform(Transfo);
-
+
// Surface de revolution
Revol = new(Geom_SurfaceOfRevolution) (S, Ax);
- Pl = new (GeomAdaptor_HSurface)(Revol);
- Int.Perform(myGuide, Pl); // intersection surf. revol / guide
- if (Int.NbPoints() == 0) {
+ GeomAdaptor_Surface GArevol(Revol);
+ Extrema_ExtCS DistMini(myGuide->Curve(), GArevol,
+ Precision::Confusion(), Precision::Confusion());
+ Extrema_POnCurv Pc;
+ Extrema_POnSurf Ps;
+ Standard_Real theU = 0., theV = 0.;
+
+ if (!DistMini.IsDone() || DistMini.NbExt() == 0) {
#if DEB
cout <<"LocationGuide : Pas d'intersection"<<endl;
TraceRevol(t, U, myLaw, mySec, myCurve, Trans);
SOS = Standard_True;
math_Vector RR(1,3);
Result.Root(RR);
- PInt.SetValues(P, RR(2), RR(3), RR(1), IntCurveSurface_Out);
+ PInt.SetValues(P, RR(2), RR(3), RR(1), IntCurveSurface_Out);
+ theU = PInt.U();
+ theV = PInt.V();
}
else {
#if DEB
}
else { // on prend le point d'intersection
// d'angle le plus proche de P
- PInt = Int.Point(1);
- a1 = PInt.U();
+
+ Standard_Real MinDist = RealLast();
+ Standard_Integer jref = 0;
+ for (Standard_Integer j = 1; j <= DistMini.NbExt(); j++)
+ {
+ Standard_Real aDist = DistMini.SquareDistance(j);
+ if (aDist < MinDist)
+ {
+ MinDist = aDist;
+ jref = j;
+ }
+ }
+ MinDist = Sqrt(MinDist);
+ DistMini.Points(jref, Pc, Ps);
+
+ Ps.Parameter(theU, theV);
+ a1 = theU;
+
InGoodPeriod (CurAngle, 2*M_PI, a1);
- Standard_Real Dmin = Abs(a1-CurAngle);
- for (Standard_Integer jj=2;jj<=Int.NbPoints();jj++) {
- a2 = Int.Point(jj).U();
- InGoodPeriod (CurAngle, 2*M_PI, a2);
- if (Abs(a2-CurAngle) < Dmin) {
- PInt = Int.Point(jj);
- Dmin = Abs(a2-CurAngle);
- }//if
- }//for
}//else
// Controle de w
- w = PInt.W();
+ w = Pc.Parameter();
+
if (ii>1) {
Diff = w - myPoles2d->Value(1, ii-1).Y();
if (Abs(Diff) > DeltaG) {
#endif
}
//Recadrage de l'angle.
- Angle = PInt.U();
+ Angle = theU;
+
if (ii > 1) {
Diff = Angle - OldAngle;
if (Abs(Diff) > M_PI) {
//Recadrage du V
- v = PInt.V();
+ v = theV;
+
if (ii > 1) {
if (uperiodic) {
InGoodPeriod (myPoles2d->Value(2, ii-1).Y(), UPeriod, v);
OrigParam2 = Param2;
}
+//==================================================================
+//Function : ComputeAutomaticLaw
+//Purpose :
+//==================================================================
+GeomFill_PipeError GeomFill_LocationGuide::ComputeAutomaticLaw(Handle(TColgp_HArray1OfPnt2d)& ParAndRad) const
+{
+ gp_Pnt P;
+ gp_Vec T,N,B;
+ Standard_Integer ii;
+ Standard_Real t;
+
+ GeomFill_PipeError theStatus = GeomFill_PipeOk;
+
+ Standard_Real f = myCurve->FirstParameter();
+ Standard_Real l = myCurve->LastParameter();
+
+ ParAndRad = new TColgp_HArray1OfPnt2d(1, myNbPts);
+ for (ii = 1; ii <= myNbPts; ii++)
+ {
+ t = Standard_Real(myNbPts - ii)*f + Standard_Real(ii - 1)*l;
+ t /= (myNbPts-1);
+ myCurve->D0(t, P);
+ Standard_Boolean Ok = myLaw->D0(t, T, N, B);
+ if (!Ok)
+ {
+ theStatus = myLaw->ErrorStatus();
+ return theStatus;
+ }
+ gp_Pnt PointOnGuide = myLaw->CurrentPointOnGuide();
+ Standard_Real CurWidth = P.Distance(PointOnGuide);
+
+ gp_Pnt2d aParamWithRadius(t, CurWidth);
+ ParAndRad->SetValue(ii, aParamWithRadius);
+ }
+
+ return theStatus;
+}
uses
HCurve from Adaptor3d,
- Real from Standard
+ Real from Standard,
+ Pnt from gp
raises
OutOfRange, NotImplemented
Param2 : Real)
is deferred;
+ CurrentPointOnGuide(me)
+ ---Purpose: Returns the current point on guide
+ -- found by D0, D1 or D2.
+ returns Pnt from gp;
+
fields
myGuide : HCurve from Adaptor3d is protected;
myTrimG : HCurve from Adaptor3d is protected;
+ myCurPointOnGuide : Pnt from gp is protected;
end TrihedronWithGuide;
return myGuide;
}
+//=======================================================================
+//function : CurrentPointOnGuide
+//purpose :
+//=======================================================================
+gp_Pnt GeomFill_TrihedronWithGuide::CurrentPointOnGuide() const
+{
+ return myCurPointOnGuide;
+}
--- /dev/null
+puts "============"
+puts "OCC24305"
+puts "============"
+puts ""
+#######################################################################
+# New option in BRepOffsetAPI_MakePipeShell algofithm: the swept shell with varying width of section bounded by auxiliary spine
+#######################################################################
+
+restore [locate_data_file bug24305_mainSpine.brep] sp
+restore [locate_data_file bug24305_auxSpine.brep] aux
+restore [locate_data_file bug24305_profile.brep] pr
+
+wire sp sp
+wire aux aux
+mksweep sp
+
+setsweep -G aux 1 2
+addsweep pr
+buildsweep result
+
+set square 69608
+
+set nb_v_good 12
+set nb_e_good 16
+set nb_w_good 5
+set nb_f_good 5
+set nb_sh_good 1
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 39
+
+set 2dviewer 1