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.
* 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
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:**
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:
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 ))
// Sort input edges
TopoDS_Edge edge1, edge2;
+ Standard_Real aTolMax = Precision::Infinite();
if (firstCall) {
// Take the longest edge as first
Standard_Real f, l;
edge1 = edgeLast;
edge2 = edgeFirst;
whichSec = 2;
+ aTolMax = len2 / 2.;
}
else {
edge1 = edgeFirst;
edge2 = edgeLast;
whichSec = 1;
+ aTolMax = len1 / 2.;
}
}
else {
TopLoc_Location loc2;
Handle(Geom_Surface) surf2;
- //Handle(Geom2d_Curve) c2d2, c2d21;
+ Handle(Geom2d_Curve) c2d2edge;
// Standard_Real firstOld, lastOld;
TopTools_ListIteratorOfListOfShape itf2;
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;
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
}
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) {
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;
}
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)
}
}
- 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;
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());
- }
+ Handle(Geom2d_Curve) aProjCurve;
+ Standard_Real aTolReached_3 = RealLast();
+ if (!isSeam2edge && myTolerance < aTolMax)
+ {
+ 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);
}
- if (maxTol >= 0. && maxTol < tolReached)
+ else
{
- if (tolReached > MaxTolerance())
- {
- // Set tolerance directly to overwrite too large tolerance
- static_cast<BRep_TEdge*>(edge.TShape().get())->Tolerance(maxTol);
+ //
+ 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());
+ }
}
- else
+ if (maxTol >= 0. && maxTol < tolReached)
{
- // just update tolerance with computed distance
- aBuilder.UpdateEdge(edge, maxTol);
+ 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);
}
}
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
//! 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);
#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
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);
+ }
+}
\ No newline at end of file
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;
//
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())
{
}
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));
}
}
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
"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",
}
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);
}
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
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
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
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
sewing result 0.1 a
-checkmaxtol result -ref 0.40493352048584974
+checkmaxtol result -ref 0.21794517334615857
checknbshapes result -shell 1
checkfreebounds result 0
--- /dev/null
+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."
+}
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
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]
}
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
\ No newline at end of file
-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
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
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
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