1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

0027651: Add projection support in sewing pcurves handling

1. BRepLib.hxx, BRepLib_1.cxx - implementation of method SetPCurve(...), which can build new pcurve by projection, if pcurve to be set is not  satisfied by tolerance criterium.

2. BRepBuilderAPI_Sewing.cxx - modification of method SameParameterEdge(...) using new method SetPCurve(...)

3. BRepTest/BRepTest_BasicCommands.cxx - implementation Draw command SetPCurve

4. Approx_ComputeCLine.gxx, BRepOffsetAPI_DraftAngle.cxx, ProjLib_ProjectedCurve.cxx - small modification to fix regression.

5. Modification of tests according to current behavior of sewing algorithm.

6. Test case added
 bugs/modalg_6/bug27651

7. dox/user_guides/draw_test_harness/draw_test_harness.md
Documentation update.
This commit is contained in:
ifv
2018-05-25 15:21:04 +03:00
parent e83d440f92
commit 680338d6f3
21 changed files with 619 additions and 80 deletions

View File

@@ -6093,6 +6093,7 @@ This group of commands is used to create topology from shapes and to extract sha
* To create faces, use the **mkplane**, **mkface** commands.
* To extract the geometry from edges or faces, use the **mkcurve** and **mkface** commands.
* To extract the 2d curves from edges or faces, use the **pcurve** command.
* To add/set the 2d curves to edges of face, use the **addpcurve** or **setpcurve** command.
@subsubsection occt_draw_7_2_1 vertex
@@ -6415,14 +6416,16 @@ vertex v2 10 0 0
edge e v1 v2
~~~~~
@subsubsection occt_draw_7_2_9 pcurve
@subsubsection occt_draw_7_2_9 pcurve, addpcurve, setpcurve
Syntax:
~~~~~
pcurve [name edgename] facename
addpcurve edge 2dcurve face [tol (default 1.e-7)]
setpcurve edge 2dcurve face [tol (default 1.e-4)]
~~~~~
**pcurve**
Extracts the 2d curve of an edge on a face. If only the face is specified, the command extracts all the curves and colors them according to their orientation. This is useful in checking to see if the edges in a face are correctly oriented, i.e. they turn counter-clockwise. To make curves visible, use a fitted 2d view.
**Example:**
@@ -6436,6 +6439,14 @@ pcurve p
2dfit
~~~~~
**addpcurve**,
Add given pcurve to edge of face, update edge tolerance.
**setpcurve**
Add given pcurve to edge, if pcurve cannot be set with tolerance less then tol,
algorithm builds new pcurve by projecting edge on face and sets it.
@subsubsection occt_draw_7_2_10 chfi2d
Syntax:

View File

@@ -178,10 +178,12 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
Standard_Boolean aStopCutting = Standard_False;
if (aNbCut >= aNbComp)
{
if (aNbCut > aNbImp)
if (aNbCut > aNbImp + 1)
{
aStopCutting = Standard_True;
}
aNbCut = 0;
aNbImp = 0;
}
// is new decision better?
if (!Ok && (Abs(myfirstU - mylastU) <= TolU || aMaxSegments >= aMaxSegments1 || aStopCutting ))

View File

@@ -587,6 +587,7 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
// Sort input edges
TopoDS_Edge edge1, edge2;
Standard_Real aTolMax = Precision::Infinite();
if (firstCall) {
// Take the longest edge as first
Standard_Real f, l;
@@ -600,11 +601,13 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
edge1 = edgeLast;
edge2 = edgeFirst;
whichSec = 2;
aTolMax = len2 / 2.;
}
else {
edge1 = edgeFirst;
edge2 = edgeLast;
whichSec = 1;
aTolMax = len1 / 2.;
}
}
else {
@@ -747,7 +750,7 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
TopLoc_Location loc2;
Handle(Geom_Surface) surf2;
//Handle(Geom2d_Curve) c2d2, c2d21;
Handle(Geom2d_Curve) c2d2edge;
// Standard_Real firstOld, lastOld;
TopTools_ListIteratorOfListOfShape itf2;
@@ -755,6 +758,7 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
else itf2.Initialize(listFacesFirst);
Standard_Boolean isResEdge = Standard_False;
TopoDS_Face fac2;
Standard_Boolean isSeam2edge = Standard_False;
for (; itf2.More(); itf2.Next()) {
Handle(Geom2d_Curve) c2d2, c2d21;
Standard_Real firstOld, lastOld;
@@ -763,6 +767,7 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
surf2 = BRep_Tool::Surface(fac2, loc2);
Standard_Boolean isSeam2 = ((IsUClosedSurface(surf2,edge2,loc2) || IsVClosedSurface(surf2,edge2,loc2)) &&
BRep_Tool::IsClosed(TopoDS::Edge(edge2),fac2));
isSeam2edge = isSeam2;
if (isSeam2) {
if (!myNonmanifold) return TopoDS_Edge();
TopoDS_Shape aTmpShape = edge2.Reversed(); //for porting
@@ -770,7 +775,6 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
}
c2d2 = BRep_Tool::CurveOnSurface(edge2, fac2, firstOld, lastOld);
if (c2d2.IsNull() && c2d21.IsNull()) continue;
if (!c2d21.IsNull()) {
c2d21 = Handle(Geom2d_Curve)::DownCast(c2d21->Copy());
if (!secForward) {
@@ -800,7 +804,9 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
c2d2 = SameRange(c2d2,firstOld,lastOld,first,last);
if (c2d2.IsNull()) continue;
//
c2d2edge = c2d2;
//
// Add second PCurve
Standard_Boolean isSeam = Standard_False;
TopAbs_Orientation Ori = TopAbs_FORWARD;
@@ -890,6 +896,20 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
}
Standard_Real tolReached = Precision::Infinite();
Standard_Boolean isSamePar = Standard_False;
// Save initial tolerances of edge before SameParameter
Standard_Real aToledge = BRep_Tool::Tolerance(edge);
TopoDS_Vertex aV1edge, aV2edge;
TopExp::Vertices(edge, aV1edge, aV2edge);
Standard_Real aTolV1 = Precision::Confusion(), aTolV2 = Precision::Confusion();
//
if (!aV1edge.IsNull())
{
aTolV1 = BRep_Tool::Tolerance(aV1edge);
}
if (!aV2edge.IsNull())
{
aTolV2 = BRep_Tool::Tolerance(aV2edge);
}
try
{
if( isResEdge)
@@ -903,23 +923,23 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
}
}
catch(Standard_Failure const&)
catch(Standard_Failure)
{
isSamePar = Standard_False;
}
if (firstCall && ( !isResEdge || !isSamePar || tolReached > myTolerance)) {
if (firstCall && (!isResEdge || !isSamePar || tolReached > myTolerance)) {
Standard_Integer whichSecn = whichSec;
// Try to merge on the second section
Standard_Boolean second_ok = Standard_False;
TopoDS_Edge s_edge = SameParameterEdge(edgeFirst,edgeLast,listFacesFirst,listFacesLast,
secForward,whichSecn,Standard_False);
if( !s_edge.IsNull())
TopoDS_Edge s_edge = SameParameterEdge(edgeFirst, edgeLast, listFacesFirst, listFacesLast,
secForward, whichSecn, Standard_False);
if (!s_edge.IsNull())
{
Standard_Real tolReached_2 = BRep_Tool::Tolerance(s_edge);
second_ok = ( BRep_Tool::SameParameter(s_edge) && tolReached_2 < tolReached );
if( second_ok)
Standard_Real tolReached_2 = BRep_Tool::Tolerance(s_edge);
second_ok = (BRep_Tool::SameParameter(s_edge) && tolReached_2 < tolReached);
if (second_ok)
{
edge = s_edge;
whichSec = whichSecn;
@@ -929,56 +949,73 @@ TopoDS_Edge BRepBuilderAPI_Sewing::SameParameterEdge(const TopoDS_Edge& edgeFirs
if (!second_ok && !edge.IsNull()) {
GeomAdaptor_Curve c3dAdapt(c3d);
// Discretize edge curve
Standard_Integer i, j, nbp = 23;
Standard_Real deltaT = (last3d - first3d) / (nbp -1);
TColgp_Array1OfPnt c3dpnt(1,nbp);
for (i = 1; i <= nbp; i++)
c3dpnt(i) = c3dAdapt.Value(first3d + (i-1)*deltaT);
Standard_Real dist = 0., maxTol = -1.0;
Standard_Boolean more = Standard_True;
for (j = 1; more; j++) {
Handle(Geom2d_Curve) c2d2;
BRep_Tool::CurveOnSurface(edge, c2d2, surf2, loc2, first, last, j);
more = !c2d2.IsNull();
if (more) {
Handle(Geom_Surface) aS = surf2;
if(!loc2.IsIdentity())
aS = Handle(Geom_Surface)::DownCast(surf2->Transformed ( loc2 ));
Standard_Real dist2 = 0.;
deltaT = (last - first) / (nbp - 1);
for (i = 1; i <= nbp; i++) {
gp_Pnt2d aP2d = c2d2->Value(first + (i -1)*deltaT);
gp_Pnt aP2(0.,0.,0.);
aS->D0(aP2d.X(),aP2d.Y(), aP2);
gp_Pnt aP1 = c3dpnt(i);
dist = aP2.SquareDistance(aP1);
if (dist > dist2)
dist2 = dist;
}
maxTol = Max(sqrt(dist2) * (1. + 1e-7), Precision::Confusion());
}
}
if (maxTol >= 0. && maxTol < tolReached)
Handle(Geom2d_Curve) aProjCurve;
Standard_Real aTolReached_3 = RealLast();
if (!isSeam2edge && myTolerance < aTolMax)
{
if (tolReached > MaxTolerance())
{
// Set tolerance directly to overwrite too large tolerance
static_cast<BRep_TEdge*>(edge.TShape().get())->Tolerance(maxTol);
}
else
{
// just update tolerance with computed distance
aBuilder.UpdateEdge(edge, maxTol);
}
static_cast<BRep_TEdge*>(edge.TShape().get())->Tolerance(aToledge);
static_cast<BRep_TVertex*>(aV1edge.TShape().get())->Tolerance(aTolV1);
static_cast<BRep_TVertex*>(aV2edge.TShape().get())->Tolerance(aTolV2);
BRepLib::SetPCurve(edge, c2d2edge, fac2, myTolerance,
aTolReached_3, aProjCurve);
}
else
{
//
GeomAdaptor_Curve c3dAdapt(c3d);
// Discretize edge curve
Standard_Integer i, j, nbp = 23;
Standard_Real deltaT = (last3d - first3d) / (nbp - 1);
TColgp_Array1OfPnt c3dpnt(1, nbp);
for (i = 1; i <= nbp; i++)
c3dpnt(i) = c3dAdapt.Value(first3d + (i - 1)*deltaT);
Standard_Real dist = 0., maxTol = -1.0;
Standard_Boolean more = Standard_True;
for (j = 1; more; j++) {
Handle(Geom2d_Curve) c2d2;
BRep_Tool::CurveOnSurface(edge, c2d2, surf2, loc2, first, last, j);
more = !c2d2.IsNull();
if (more) {
Handle(Geom_Surface) aS = surf2;
if (!loc2.IsIdentity())
aS = Handle(Geom_Surface)::DownCast(surf2->Transformed(loc2));
Standard_Real dist2 = 0.;
deltaT = (last - first) / (nbp - 1);
for (i = 1; i <= nbp; i++) {
gp_Pnt2d aP2d = c2d2->Value(first + (i - 1)*deltaT);
gp_Pnt aP2(0., 0., 0.);
aS->D0(aP2d.X(), aP2d.Y(), aP2);
gp_Pnt aP1 = c3dpnt(i);
dist = aP2.SquareDistance(aP1);
if (dist > dist2)
dist2 = dist;
}
maxTol = Max(sqrt(dist2) * (1. + 1e-7), Precision::Confusion());
}
}
if (maxTol >= 0. && maxTol < tolReached)
{
if (tolReached > MaxTolerance())
{
// Set tolerance directly to overwrite too large tolerance
static_cast<BRep_TEdge*>(edge.TShape().get())->Tolerance(maxTol);
}
else
{
// just update tolerance with computed distance
aBuilder.UpdateEdge(edge, maxTol);
aBuilder.UpdateVertex(aV1edge, maxTol);
aBuilder.UpdateVertex(aV2edge, maxTol);
}
}
aBuilder.SameParameter(edge, Standard_True);
}
aBuilder.SameParameter(edge,Standard_True);
}
}
@@ -4744,7 +4781,7 @@ void BRepBuilderAPI_Sewing::SameParameterShape()
BRepLib::SameParameter(sec, BRep_Tool::Tolerance(sec));
}
catch (Standard_Failure const&) {
catch (Standard_Failure) {
#ifdef OCCT_DEBUG
std::cout << "Fail: BRepBuilderAPI_Sewing::SameParameterShape exception in BRepLib::SameParameter" << std::endl;
#endif

View File

@@ -114,6 +114,34 @@ public:
//! return False if one of the computation failed.
Standard_EXPORT static Standard_Boolean BuildCurves3d (const TopoDS_Shape& S);
//! Sets a pcurve theC for the edge theE on the face theF.
//! Setting pcurve can include calling sameparameter algorithm.
//! theMaxTol is the maximal tolerance allowed for pcurve.
//! If given pcurve cannot be set with tolerance less then theMaxtol,
//! algorithm builds new pcurve by projecting edge on face and sets curve,
//! which provides minimal tolerance. If projecting was done, algorithm sets
//! result of projecting in theProjCurve
//! Algorithm sets in theTolReached tolerance of edge after setting pcurve.
Standard_EXPORT static void SetPCurve(const TopoDS_Edge& theE,
const Handle(Geom2d_Curve)& theC,
const TopoDS_Face& theF, const Standard_Real theMaxTol,
Standard_Real& theTolReached, Handle(Geom2d_Curve)& theProjCurve);
//! Sets the pcurve theC1, theC2 for the edge theE on the closed face theF.
//! Setting pcurve can include calling sameparameter algorithm.
//! theMaxTol is the maximal tolerance allowed for pcurve.
//! If given pcurve cannot be set with tolerance less then theMaxtol,
//! algorithm builds new pcurves by projecting edge on face and sets curves,
//! which provides minimal tolerance. If projecting was done, algorithm sets
//! result of projecting in theProjCurve1 and theProjCurve2.
//! Algorithm sets in theTolReached tolerance of edge after setting pcurve.
Standard_EXPORT static void SetPCurve(const TopoDS_Edge& theE,
const Handle(Geom2d_Curve)& theC1, const Handle(Geom2d_Curve)& theC2,
const TopoDS_Face& theF, const Standard_Real theMaxTol,
Standard_Real& theTolReached,
Handle(Geom2d_Curve)& theProjCurve1,
Handle(Geom2d_Curve)& theProjCurve2);
//! Builds pcurve of edge on face if the surface is plane, and updates the edge.
Standard_EXPORT static void BuildPCurveForEdgeOnPlane(const TopoDS_Edge& theE, const TopoDS_Face& theF);

View File

@@ -21,7 +21,20 @@
#include <Precision.hxx>
#include <TopExp.hxx>
#include <TopoDS_Vertex.hxx>
#include <BRepCheck_Edge.hxx>
#include <BRepAdaptor_HSurface.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <BRepAdaptor_HCurve.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <ProjLib_ProjectedCurve.hxx>
#include <AppParCurves_Constraint.hxx>
#include <ProjLib.hxx>
#include <GeomLib_CheckCurveOnSurface.hxx>
#include <GeomAdaptor.hxx>
#include <Adaptor3d_CurveOnSurface.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <GeomLib.hxx>
#include <BRep_TEdge.hxx>
//=======================================================================
// function: findNearestValidPoint
// purpose : Starting from the appointed end of the curve, find the nearest
@@ -282,3 +295,379 @@ void BRepLib::BuildPCurveForEdgeOnPlane(const TopoDS_Edge& aE,
aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2, &isStored);
bToUpdate = !isStored && !aC2D.IsNull();
}
//=======================================================================
//function : CompTol
//purpose :
//=======================================================================
static Standard_Real CompTol(const Handle(Geom_Curve)& theC3D,
const Handle(Geom2d_Curve)& theC2D,
const Handle(Geom_Surface)& theS,
const Standard_Real theFirstPar,
const Standard_Real theLastPar)
{
Standard_Real aTolRange = Max(Precision::PConfusion(),
0.001 * (theLastPar - theFirstPar));
GeomLib_CheckCurveOnSurface aCheckDist(theC3D, theS, theFirstPar, theLastPar, aTolRange);
aCheckDist.Perform(theC2D);
Standard_Real aTolR = 0.;
if (aCheckDist.IsDone())
{
aTolR = aCheckDist.MaxDistance();
}
else
{
const Standard_Integer aNbPnts = 23;
TColStd_Array1OfReal aPars(1, aNbPnts);
Standard_Integer i;
Standard_Real t, dt = (theLastPar - theFirstPar) / (aNbPnts - 1);
aPars(1) = theFirstPar;
aPars(aNbPnts) = theLastPar;
for (i = 2, t = theFirstPar + dt; i < aNbPnts; ++i, t += dt)
{
aPars(i) = t;
}
Handle(Geom2dAdaptor_HCurve) aG2dAHC = new Geom2dAdaptor_HCurve(theC2D);
GeomAdaptor_Curve aGAC(theC3D);
Handle(GeomAdaptor_HSurface) aGAHS = new GeomAdaptor_HSurface(theS);
Adaptor3d_CurveOnSurface aConS(aG2dAHC, aGAHS);
GeomLib::EvalMaxParametricDistance(aConS, aGAC, 1., aPars, aTolR);
aTolR *= 1.5; //possible deflection
}
return aTolR;
}
//=======================================================================
//function : UpdateTol
//purpose :
//=======================================================================
static void UpdateTol(const TopoDS_Edge& theE, const Standard_Real theTol)
{
BRep_Builder aBB;
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(theE, aV1, aV2);
if (!aV1.IsNull())
{
aBB.UpdateVertex(aV1, theTol);
}
if (!aV2.IsNull())
{
aBB.UpdateVertex(aV2, theTol);
}
aBB.UpdateEdge(theE, theTol);
}
//=======================================================================
//function : SetPCurve
//purpose :
//=======================================================================
void BRepLib::SetPCurve(const TopoDS_Edge& theE,
const Handle(Geom2d_Curve)& theC,
const TopoDS_Face& theF,
const Standard_Real theMaxTol,
Standard_Real& theTolReached, Handle(Geom2d_Curve)& theProjCurve)
{
Standard_Real aSMTol = Precision::PConfusion();
Standard_Real aTol = BRep_Tool::Tolerance(theE);
BRep_Builder aBB;
Standard_Real fr, lr, f, l;
BRep_Tool::Range(theE, fr, lr);
Handle(Geom2d_Curve) aC = theC;
f = theC->FirstParameter();
l = theC->LastParameter();
if (!(Precision::IsInfinite(f) || Precision::IsInfinite(l)))
{
GeomLib::SameRange(aSMTol, theC, f, l, fr, lr, aC);
}
aBB.UpdateEdge(theE, aC, theF, aTol);
Handle(Geom_Surface) anS = BRep_Tool::Surface(theF);
Handle(Geom_Curve) aC3D = BRep_Tool::Curve(theE, f, l);
Standard_Real aTol1 = CompTol(aC3D, aC, anS, fr, lr);
if (aTol1 <= aTol)
{
theTolReached = aTol1;
aBB.SameParameter(theE, Standard_True);
return;
}
else if (theMaxTol < aTol && aTol1 < 2.*aTol)
{
theTolReached = aTol1;
UpdateTol(theE, theTolReached);
return;
}
aBB.SameParameter(theE, Standard_False);
Standard_Real aNewTol = -1;
BRepLib::SameParameter(theE, aTol, aNewTol, Standard_True);
if (aNewTol > 0)
{
//Set old tolerance for edge, which has been changed by sameparameter
static_cast<BRep_TEdge*>(theE.TShape().get())->Tolerance(aTol);
}
if (aNewTol > 0.)
{
aC = BRep_Tool::CurveOnSurface(theE, theF, f, l);
aNewTol = CompTol(aC3D, aC, anS, fr, lr);
if (aNewTol < theMaxTol)
{
aBB.SameParameter(theE, Standard_True);
theTolReached = aNewTol;
UpdateTol(theE, theTolReached);
return ;
}
}
//Projection
Handle(BRepAdaptor_HSurface) aBAHS =
new BRepAdaptor_HSurface(BRepAdaptor_Surface(theF, Standard_False));
Handle(BRepAdaptor_HCurve) aBAHC = new BRepAdaptor_HCurve(theE);
ProjLib_ProjectedCurve aProjCurv(aBAHS);
Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1;
Standard_Real aMaxDist = Max(1.e3 * theMaxTol, aNewTol);
Standard_Real aTR = Precision::Confusion();
Standard_Real aMaxTol = 1.e3 * aTR; //0.0001
Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS);
AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint;
if (theMaxTol >= aMaxTol || aNewTol > 10. * theMaxTol)
{
aTR = aMaxTol;
if (aNewTol >= 1.)
{
aTR = Min(10. * aTR, theMaxTol);
}
if (!isAnaSurf )
{
aBndPnt = AppParCurves_PassPoint;
}
}
//
theTolReached = RealLast();
aProjCurv.Load(aTR);
aProjCurv.SetDegree(aDegMin, aDegMax);
aProjCurv.SetMaxSegments(aMaxSegments);
aProjCurv.SetBndPnt(aBndPnt);
aProjCurv.SetMaxDist(aMaxDist);
aProjCurv.Perform(aBAHC);
ProjLib::MakePCurveOfType(aProjCurv, theProjCurve);
if (!theProjCurve.IsNull())
{
Standard_Real pf = theProjCurve->FirstParameter(),
pl = theProjCurve->LastParameter();
if (!(Precision::IsInfinite(pf) || Precision::IsInfinite(pl)))
{
if (Abs(pf - fr) > aSMTol || Abs(pl - lr) > aSMTol)
{
aC.Nullify();
GeomLib::SameRange(aSMTol, theProjCurve, pf, pl, fr, lr, aC);
if (!aC.IsNull() && theProjCurve != aC)
{
theProjCurve = aC;
}
}
}
Standard_Real aTolR = CompTol(aC3D, theProjCurve, anS, fr, lr);
//
if ((aNewTol > 0. && aTolR < aNewTol) || aNewTol < 0.)
{
theTolReached = aTolR;
//
//Set new pcurve
aBB.UpdateEdge(theE, theProjCurve, theF, theTolReached);
UpdateTol(theE, theTolReached);
aBB.SameParameter(theE, Standard_True);
}
else
{
if (aNewTol > 0.)
{
theTolReached = aNewTol;
}
else
{
theTolReached = aTol1;
}
UpdateTol(theE, theTolReached);
aBB.SameParameter(theE, Standard_True);
}
}
else
{
if (aNewTol > 0.)
{
theTolReached = aNewTol;
}
else
{
theTolReached = aTol1;
}
UpdateTol(theE, theTolReached);
aBB.SameParameter(theE, Standard_True);
}
}
//=======================================================================
//function : SetPCurve
//purpose :
//=======================================================================
void BRepLib::SetPCurve(const TopoDS_Edge& theE,
const Handle(Geom2d_Curve)& theC1, const Handle(Geom2d_Curve)& theC2,
const TopoDS_Face& theF,
const Standard_Real theMaxTol,
Standard_Real& theTolReached,
Handle(Geom2d_Curve)& theProjCurve1,
Handle(Geom2d_Curve)& theProjCurve2)
{
Standard_Real aSMTol = Precision::PConfusion();
Standard_Real aTol = BRep_Tool::Tolerance(theE);
BRep_Builder aBB;
Standard_Real fr, lr, f, l;
BRep_Tool::Range(theE, fr, lr);
Handle(Geom2d_Curve) aC1 = theC1, aC2 = theC2;
f = theC1->FirstParameter();
l = theC1->LastParameter();
if (!(Precision::IsInfinite(f) || Precision::IsInfinite(l)))
{
GeomLib::SameRange(aSMTol, theC1, f, l, fr, lr, aC1);
}
f = theC2->FirstParameter();
l = theC2->LastParameter();
if (!(Precision::IsInfinite(f) || Precision::IsInfinite(l)))
{
GeomLib::SameRange(aSMTol, theC2, f, l, fr, lr, aC2);
}
aBB.UpdateEdge(theE, aC1, aC2, theF, aTol);
Handle(Geom_Surface) anS = BRep_Tool::Surface(theF);
Handle(Geom_Curve) aC3D = BRep_Tool::Curve(theE, f, l);
Standard_Real aTol1 = CompTol(aC3D, aC1, anS, fr, lr);
aTol1 = Max(aTol1, CompTol(aC3D, aC2, anS, fr, lr));
if (aTol1 <= aTol)
{
theTolReached = aTol1;
aBB.SameParameter(theE, Standard_True);
return;
}
aBB.SameParameter(theE, Standard_False);
Standard_Real aNewTol = -1;
BRepLib::SameParameter(theE, aTol, aNewTol, Standard_False);
if (aNewTol > 0)
{
//Set old tolerance for edge, which has been changed by sameparameter
static_cast<BRep_TEdge*>(theE.TShape().get())->Tolerance(aTol);
}
if (aNewTol > 0. && aNewTol < theMaxTol)
{
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(theE, aV1, aV2);
if (!aV1.IsNull())
{
aBB.UpdateVertex(aV1, aNewTol);
}
if (!aV2.IsNull())
{
aBB.UpdateVertex(aV2, aNewTol);
}
theTolReached = aNewTol;
return;
}
//Projection
Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(theF);
Handle(BRepAdaptor_HCurve) aBAHC = new BRepAdaptor_HCurve(theE);
ProjLib_ProjectedCurve aProjCurv(aBAHS);
Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1;
Standard_Real aMaxDist = Max(1.e3 * theMaxTol, aNewTol);
Standard_Real aTR = Precision::Confusion();
Standard_Real aMaxTol = 1.e3 * aTR; //0.0001
Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS);
AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint;
if (theMaxTol >= aMaxTol || aNewTol > 10. * theMaxTol)
{
aTR = aMaxTol;
if (aNewTol >= 1.)
{
aTR = Min(10. * aTR, theMaxTol);
}
if (!isAnaSurf)
{
aBndPnt = AppParCurves_PassPoint;
}
}
//
theTolReached = RealLast();
aProjCurv.Load(aTR);
aProjCurv.SetDegree(aDegMin, aDegMax);
aProjCurv.SetMaxSegments(aMaxSegments);
aProjCurv.SetBndPnt(aBndPnt);
aProjCurv.SetMaxDist(aMaxDist);
aProjCurv.Perform(aBAHC);
Handle(Geom2d_Curve) aCProj;
ProjLib::MakePCurveOfType(aProjCurv, aCProj);
if (!aCProj.IsNull())
{
Standard_Real pf = aCProj->FirstParameter(),
pl = aCProj->LastParameter();
if (!(Precision::IsInfinite(pf) || Precision::IsInfinite(pl)))
{
if (Abs(pf - fr) > aSMTol || Abs(pl - lr) > aSMTol)
{
aC1.Nullify();
GeomLib::SameRange(aSMTol, aCProj, pf, pl, fr, lr, aC1);
if (!aC1.IsNull() && aCProj != aC1)
{
aCProj = aC1;
}
}
}
Standard_Real aTolR = CompTol(aC3D, aCProj, anS, fr, lr);
//
if ((aNewTol > 0. && aTolR < aNewTol) || aNewTol < 0.)
{
theTolReached = aTolR;
//
gp_Pnt2d aP1, aP2, aPProj;
Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(theE, theF, f, l);
aP1 = aPC->Value(f);
aPC = BRep_Tool::CurveOnSurface(TopoDS::Edge(theE.Reversed()), theF, f, l);
aP2 = aPC->Value(f);
aPProj = aCProj->Value(f);
Standard_Real Dist1, Dist2;
Dist1 = aPProj.Distance(aP1);
Dist2 = aPProj.Distance(aP2);
if (Dist1 < Dist2) {
theProjCurve1 = aCProj;
Handle(Geom2d_Geometry) GG = aCProj->Translated(aP1, aP2);
theProjCurve2 = Handle(Geom2d_Curve)::DownCast(GG);
}
else {
theProjCurve2 = aCProj;
Handle(Geom2d_Geometry) GG = aCProj->Translated(aP2, aP1);
theProjCurve1 = Handle(Geom2d_BSplineCurve)::DownCast(GG);
}
//Set new pcurves
aBB.UpdateEdge(theE, theProjCurve1, theProjCurve2, theF, aTolR);
UpdateTol(theE, theTolReached);
aBB.SameParameter(theE, Standard_True);
}
else
{
if (aNewTol > 0.)
{
theTolReached = aNewTol;
}
else
{
theTolReached = aTol1;
}
UpdateTol(theE, theTolReached);
aBB.SameParameter(theE, Standard_True);
}
}
else
{
if (aNewTol > 0.)
{
theTolReached = aNewTol;
}
else
{
theTolReached = aTol1;
}
UpdateTol(theE, theTolReached);
aBB.SameParameter(theE, Standard_True);
}
}

View File

@@ -960,7 +960,7 @@ void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
anExp.Init(myShape, TopAbs_EDGE);
for(; anExp.More(); anExp.Next())
{
const TopoDS_Shape& anE = anExp.Current();
const TopoDS_Edge& anE = TopoDS::Edge(anExp.Current());
//Skip old (not modified) edges
if(anInitEdges.Contains(anE))
continue;
@@ -971,7 +971,7 @@ void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
//
aNewEdges.Add(anE);
//
Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
Standard_Real anETol = BRep_Tool::Tolerance(anE);
TopoDS_Iterator anIter(anE);
for(; anIter.More(); anIter.Next())
{
@@ -997,6 +997,18 @@ void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
}
else
{
gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
Standard_Real f, l;
TopLoc_Location anL;
const Handle(Geom_Curve)& aECrv = BRep_Tool::Curve(TopoDS::Edge(anE), anL, f, l);
Standard_Real aVPar = BRep_Tool::Parameter(aVtx, anE);
gp_Pnt aCP = aECrv->Value(aVPar);
if (!anL.IsIdentity())
{
aCP.Transform(anL.Transformation());
}
Standard_Real aD = aVPnt.Distance(aCP);
aBB.UpdateVertex(aVtx, aD);
aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
}
}

View File

@@ -110,6 +110,30 @@ static Standard_Integer addpcurve(Draw_Interpretor& , Standard_Integer n, const
return 0;
}
//=======================================================================
// setpcurve
//=======================================================================
static Standard_Integer setpcurve(Draw_Interpretor&, Standard_Integer n, const char** a)
{
if (n < 4) return 1;
TopoDS_Shape E = DBRep::Get(a[1]);
if (E.IsNull()) return 1;
Handle(Geom2d_Curve) PC = DrawTrSurf::GetCurve2d(a[2]);
TopoDS_Shape F = DBRep::Get(a[3]);
Standard_Real tol = 1.e-4;
if (n > 4) {
tol = Draw::Atof(a[4]);
}
//BRep_Builder BB;
//BB.UpdateEdge(TopoDS::Edge(E), PC, TopoDS::Face(F), tol);
Standard_Real tolreached;
Handle(Geom2d_Curve) ProjC;
BRepLib::SetPCurve(TopoDS::Edge(E), PC, TopoDS::Face(F), tol,
tolreached, ProjC);
DBRep::Set(a[1], E);
return 0;
}
//=======================================================================
// transform
@@ -1402,6 +1426,10 @@ void BRepTest::BasicCommands(Draw_Interpretor& theCommands)
"addpcurve edge 2dcurve face [tol (default 1.e-7)]",
__FILE__,
addpcurve,g);
theCommands.Add("setpcurve",
"addpcurve edge 2dcurve face [tol (default 1.e-4)]",
__FILE__,
setpcurve, g);
theCommands.Add("reset",
"reset name1 name2 ..., remove location",

View File

@@ -237,7 +237,7 @@ static void ExtendC2d (Handle(Geom2d_BSplineCurve)& aRes,
}
gp_Lin2d BoundLin(thePole, theBoundDir); //one of the bounds of rectangle
Standard_Real ParOnLin = 0.;
if (theBoundDir.IsParallel(aDBnd, 100.*Precision::Angular()))
if (theBoundDir.IsParallel(aDBnd, Precision::PConfusion()))
{
ParOnLin = ElCLib::Parameter(aLin, thePole);
}

View File

@@ -32,7 +32,7 @@ checkprops result -s 1.8847e+07
checkshape result
checknbshapes result -vertex 964 -edge 1222 -wire 273 -face 259 -shell 18 -solid 0 -compsolid 0 -compound 1 -shape 2737
checkmaxtol result -ref 0.046734236640099257
checkmaxtol result -ref 0.0451323239933289
checknbshapes result -shell 18
checkfreebounds result 926
checkview -display result -3d -path ${imagedir}/${test_image}.png

View File

@@ -32,7 +32,7 @@ checkprops result -s 1.8847e+07
checkshape result
checknbshapes result -vertex 964 -edge 1222 -wire 273 -face 259 -shell 18 -solid 0 -compsolid 0 -compound 1 -shape 2737
checkmaxtol result -ref 0.046734236640099257
checkmaxtol result -ref 0.0451323239933289
checknbshapes result -shell 18
checkfreebounds result 926
checkview -display result -3d -path ${imagedir}/${test_image}.png

View File

@@ -28,7 +28,7 @@ if { ${minTolerance} > ${VertexTolerance} } {
checkreal "Min tolerance" ${minTolerance} ${oTolerance} 0 0.001
checkmaxtol result -ref 2352.4465999220711
checkmaxtol result -ref 291.20622363265852
checknbshapes result -shell 1
checkfreebounds result 5

View File

@@ -29,7 +29,7 @@ if { $ve1 != $ve2 || $ed1 != $ed2 || $we1 != $we2} {
puts "OK OCC714: SEWING operation was made PROPERLY"
}
checkmaxtol result -ref 0.25619311354638169
checkmaxtol result -ref 0.17654971008905099
checknbshapes result -shell 1
checkfreebounds result 0

View File

@@ -12,7 +12,7 @@ igesread [locate_data_file bug25175_3.igs] a *
sewing result 0.1 a
checkmaxtol result -ref 0.40493352048584974
checkmaxtol result -ref 0.21794517334615857
checknbshapes result -shell 1
checkfreebounds result 0

View File

@@ -0,0 +1,32 @@
puts "========"
puts "0027651: Modeling Algorithms - Add projection support in sewing pcurves handling"
puts "========"
puts ""
restore [locate_data_file bug27531.brep] aS
sewing result 0.2 aS
# check result shape for validity.
checkshape result
# Check distances
set MAX_DIST 3.0
explode result E
explode result F
set log [xdistef result_3 result_1]
regexp {Max Distance = +([-0-9.+eE]+); Parameter} ${log} full aDist
if { $aDist > $MAX_DIST} {
puts "Error: First pcurve is too far from 3d curve"
} else {
puts "OK: First pcurve is OK."
}
set log [xdistef result_3 result_2]
regexp {Max Distance = +([-0-9.+eE]+); Parameter} ${log} full aDist
if { $aDist > $MAX_DIST} {
puts "Error: Second pcurve is too far from 3d curve"
} else {
puts "OK: Second pcurve is OK."
}

View File

@@ -29,7 +29,7 @@ if { ${face2} > ${face1} || ${edge2} > ${edge1} || ${vert2} > ${vert1} } {
puts "Tolerance valed. Function FixShape works CORRECTLY"
}
checkmaxtol result -ref 1.59071e+000
checkmaxtol result -ref 0.17775413987830679
checknbshapes result -shell 1
checkfreebounds result 227

View File

@@ -20,7 +20,7 @@ fit
set bop_info [bopcurves f1 f2]
regexp {Tolerance Reached=([-0-9.+eE]+)} $bop_info full Tolerance
checkreal "Reached tolerance" ${Tolerance} 5.8654166482879483e-009 1.e-7 0
checkreal "Reached tolerance" ${Tolerance} 5.8654392197230118e-09 1.e-7 0
# 2 case
set bop_info_2d [bopcurves f1 f2 -2d]

View File

@@ -30,6 +30,6 @@ if {${NbCurv} != ${GoodNbCurv}} {
}
checklength c_1 -l 2.9620641619623407
checklength c_2 -l 3.1050603628884668
checklength c_2 -l 3.105060362884668
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,4 +1,4 @@
puts "TODO OCC23674 ALL: Error : Number of faults is"
##puts "TODO OCC23674 ALL: Error : Number of faults is"
restore [locate_data_file CFI_pro15441.rle] a

View File

@@ -4,7 +4,7 @@ restore [locate_data_file CIN901_intcqhmi.rle] a
sewing result $tol a
checkmaxtol result -ref 1.91680e+001
checkmaxtol result -ref 26.246606802805864
checknbshapes result -shell 1
checkfreebounds result 3
checkfreebounds result 0
checkfaults result a 6

View File

@@ -4,7 +4,7 @@ restore [locate_data_file CIN902_intcqhmn.rle] a
sewing result $tol a
checkmaxtol result -ref 31.117378506550729
checkmaxtol result -ref 33.208410811730566
checknbshapes result -shell 1
checkfreebounds result 47
checkfaults result a 7

View File

@@ -4,7 +4,7 @@ restore [locate_data_file CIN902_intcqhmo.rle] a
sewing result $tol a
checkmaxtol result -ref 31.117378506550729
checkmaxtol result -ref 33.208410811730566
checknbshapes result -shell 1
checkfreebounds result 47
checkfaults result a 7