Handle(BRepTools_NurbsConvertModification) theModif =
Handle(BRepTools_NurbsConvertModification)::DownCast(myModification);
DoModif(S,myModification);
+ CorrectVertexTol();
}
+//=======================================================================
+//function : CorrectVertexTol
+//purpose :
+//=======================================================================
+
+void BRepBuilderAPI_NurbsConvert::CorrectVertexTol()
+{
+ TopTools_MapOfShape anInitVertices;
+ TopExp_Explorer anExp(myInitialShape, TopAbs_VERTEX);
+ for(; anExp.More(); anExp.Next())
+ {
+ anInitVertices.Add(anExp.Current());
+ }
+ //
+ Handle(BRepTools_NurbsConvertModification) aModif =
+ Handle(BRepTools_NurbsConvertModification)::DownCast(myModification);
+ BRep_Builder aBB;
+ myVtxToReplace.Clear();
+ TopTools_ListIteratorOfListOfShape anEIter(aModif->GetUpdatedEdges());
+ for(; anEIter.More(); anEIter.Next())
+ {
+ const TopoDS_Shape& anE = anEIter.Value();
+ //
+ Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
+ TopoDS_Iterator anIter(anE);
+ for(; anIter.More(); anIter.Next())
+ {
+ const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value());
+ if(anInitVertices.Contains(aVtx))
+ {
+ if(myVtxToReplace.IsBound(aVtx))
+ {
+ aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol));
+ }
+ else
+ {
+ Standard_Real aVTol = BRep_Tool::Tolerance(aVtx);
+ if(aVTol < anETol)
+ {
+ TopoDS_Vertex aNewVtx;
+ gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
+ aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
+ aNewVtx.Orientation(aVtx.Orientation());
+ myVtxToReplace.Bind(aVtx, aNewVtx);
+ }
+ }
+ }
+ else
+ {
+ aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
+ }
+ }
+ }
+ //
+ if(myVtxToReplace.IsEmpty())
+ {
+ return;
+ }
+ //
+ mySubs.Clear();
+ TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
+ for(; anIter.More(); anIter.Next())
+ {
+ mySubs.Replace(anIter.Key(), anIter.Value());
+ }
+ mySubs.Apply( myShape );
+ myShape = mySubs.Value(myShape);
+ //
+}
+
+//=======================================================================
+//function : ModifiedShape
+//purpose :
+//=======================================================================
+
+TopoDS_Shape BRepBuilderAPI_NurbsConvert::ModifiedShape
+ (const TopoDS_Shape& S) const
+{
+ if(S.ShapeType() == TopAbs_VERTEX)
+ {
+ if(myVtxToReplace.IsBound(S))
+ {
+ return myVtxToReplace(S);
+ }
+ }
+ if(myVtxToReplace.IsEmpty())
+ {
+ return myModifier.ModifiedShape(S);
+ }
+ else
+ {
+ const TopoDS_Shape& aNS = myModifier.ModifiedShape(S);
+ return mySubs.Value(aNS);
+ }
+}
+
+//=======================================================================
+//function : Modified
+//purpose :
+//=======================================================================
+
+const TopTools_ListOfShape& BRepBuilderAPI_NurbsConvert::Modified
+ (const TopoDS_Shape& F)
+{
+ myGenerated.Clear();
+ if(F.ShapeType() == TopAbs_VERTEX)
+ {
+ if(myVtxToReplace.IsBound(F))
+ {
+ myGenerated.Append(myVtxToReplace(F));
+ }
+ else
+ {
+ myGenerated.Append(myModifier.ModifiedShape(F));
+ }
+ }
+ else
+ {
+ if(myVtxToReplace.IsEmpty())
+ {
+ myGenerated.Append(myModifier.ModifiedShape(F));
+ }
+ else
+ {
+ const TopoDS_Shape& aNS = myModifier.ModifiedShape(F);
+ myGenerated.Append(mySubs.Value(aNS));
+ }
+ }
+ return myGenerated;
+}
#include <BRepBuilderAPI_ModifyShape.hxx>
#include <Standard_Boolean.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <BRepTools_ReShape.hxx>
+
class TopoDS_Shape;
Standard_EXPORT void Perform (const TopoDS_Shape& S, const Standard_Boolean Copy = Standard_False);
+ //! Returns the list of shapes modified from the shape
+ //! <S>.
+ Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& S);
+
+ //! Returns the modified shape corresponding to <S>.
+ //! S can correspond to the entire initial shape or to its subshape.
+ //! Exceptions
+ //! Standard_NoSuchObject if S is not the initial shape or
+ //! a subshape of the initial shape to which the
+ //! transformation has been applied.
+ Standard_EXPORT virtual TopoDS_Shape ModifiedShape (const TopoDS_Shape& S) const;
protected:
private:
+ Standard_EXPORT void CorrectVertexTol();
-
-
+ TopTools_DataMapOfShapeShape myVtxToReplace;
+ BRepTools_ReShape mySubs;
};
}
//=======================================================================
-//function : ModifiedFaces
+//function : Generated
//purpose :
//=======================================================================
Standard_Real Tol;
Standard_Boolean RW,RF;
if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
- myGenerated.Append(ModifiedShape (S));
-
+ if(myVtxToReplace.IsEmpty())
+ {
+ myGenerated.Append(ModifiedShape (S));
+ }
+ else
+ {
+ myGenerated.Append(mySubs.Value(ModifiedShape (S)));
+ }
}
}
return myGenerated;
}
//=======================================================================
-//function : ModifiedFaces
+//function : Modified
//purpose :
//=======================================================================
if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
// Ce n est pas une generation => peut etre une modif
- myGenerated.Append(ModifiedShape (S));
+ if(myVtxToReplace.IsEmpty())
+ {
+ myGenerated.Append(ModifiedShape (S));
+ }
+ else
+ {
+ myGenerated.Append(mySubs.Value(ModifiedShape (S)));
+ }
if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) {
- myGenerated.Clear();
+ myGenerated.Clear();
}
}
}
return myVtxToReplace(S);
}
}
- return myModifier.ModifiedShape(S);
+ if(myVtxToReplace.IsEmpty())
+ {
+ return myModifier.ModifiedShape(S);
+ }
+ else
+ {
+ const TopoDS_Shape& aNS = myModifier.ModifiedShape(S);
+ return mySubs.Value(aNS);
+ }
}
//=======================================================================
TopoDS_Vertex aNewVtx;
gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
+ aNewVtx.Orientation(aVtx.Orientation());
myVtxToReplace.Bind(aVtx, aNewVtx);
}
}
return;
}
//
- BRepTools_Substitution aSub;
+ mySubs.Clear();
TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
for(; anIter.More(); anIter.Next())
{
- TopTools_ListOfShape aSubVtx;
- aSubVtx.Append(anIter.Value());
- aSub.Substitute(anIter.Key(), aSubVtx);
- }
- aSub.Build( myShape );
- if (aSub.IsCopied( myShape ))
- {
- const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
- if (! listSh.IsEmpty())
- myShape = listSh.First();
+ mySubs.Replace(anIter.Key(), anIter.Value());
}
+ mySubs.Apply( myShape );
+ myShape = mySubs.Value(myShape);
//
}
#include <Standard_Real.hxx>
#include <Standard_Boolean.hxx>
#include <Draft_ErrorStatus.hxx>
+#include <BRepTools_ReShape.hxx>
+
class StdFail_NotDone;
class Standard_NullObject;
class Standard_NoSuchObject;
Standard_EXPORT void CorrectVertexTol();
TopTools_DataMapOfShapeShape myVtxToReplace;
-
+ BRepTools_ReShape mySubs;
};
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_SequenceOfShape.hxx>
-
+#include <GeomLib_CheckCurveOnSurface.hxx>
#include <errno.h>
//=======================================================================
//function : UVBounds
return nbocc == 2;
}
+//=======================================================================
+//function : EvalAndUpdateTol
+//purpose :
+//=======================================================================
+
+Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE,
+ const Handle(Geom_Curve)& C3d,
+ const Handle(Geom2d_Curve) C2d,
+ const Handle(Geom_Surface)& S,
+ const Standard_Real f,
+ const Standard_Real l)
+{
+ Standard_Real newtol = 0.;
+ Standard_Real first = f, last = l;
+ //Set first, last to avoid ErrosStatus = 2 because of
+ //too strong checking of limits in class CheckCurveOnSurface
+ //
+ if(!C3d->IsPeriodic())
+ {
+ first = Max(first, C3d->FirstParameter());
+ last = Min(last, C3d->LastParameter());
+ }
+ if(!C2d->IsPeriodic())
+ {
+ first = Max(first, C2d->FirstParameter());
+ last = Min(last, C2d->LastParameter());
+ }
+
+ GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
+ CT.Perform(C2d);
+ if(CT.IsDone())
+ {
+ newtol = CT.MaxDistance();
+ }
+ else
+ {
+ if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 &&
+ (C3d->IsPeriodic() || C2d->IsPeriodic())))
+ {
+ //Try to estimate by sample points
+ Standard_Integer nbint = 22;
+ Standard_Real dt = (last - first) / nbint;
+ dt = Max(dt, Precision::Confusion());
+ Standard_Real d, dmax = 0.;
+ gp_Pnt2d aP2d;
+ gp_Pnt aPC, aPS;
+ Standard_Integer cnt = 0;
+ Standard_Real t = first;
+ for(; t <= last; t += dt)
+ {
+ cnt++;
+ C2d->D0(t, aP2d);
+ C3d->D0(t, aPC);
+ S->D0(aP2d.X(), aP2d.Y(), aPS);
+ d = aPS.SquareDistance(aPC);
+ if(d > dmax)
+ {
+ dmax = d;
+ }
+ }
+ if(cnt < nbint + 1)
+ {
+ t = last;
+ C2d->D0(t, aP2d);
+ C3d->D0(t, aPC);
+ S->D0(aP2d.X(), aP2d.Y(), aPS);
+ d = aPS.SquareDistance(aPC);
+ if(d > dmax)
+ {
+ dmax = d;
+ }
+ }
+
+ newtol = 1.2 * Sqrt(dmax);
+ }
+ }
+ Standard_Real Tol = BRep_Tool::Tolerance(theE);
+ if(newtol > Tol)
+ {
+ Tol = newtol;
+ BRep_Builder B;
+ B.UpdateEdge(theE, Tol);
+ }
+
+ return Tol;
+
+}
class BRepTools_Quilt;
class BRepTools_ShapeSet;
class BRepTools_ReShape;
+class Geom_Curve;
+class Geom2d_Curve;
+class Geom_Surface;
//! The BRepTools package provides utilities for BRep
//! <B> is used to build the shape.
Standard_EXPORT static Standard_Boolean Read (TopoDS_Shape& Sh, const Standard_CString File, const BRep_Builder& B, const Handle(Message_ProgressIndicator)& PR = NULL);
+ //! Evals real tolerance of edge <theE>.
+ //! <theC3d>, <theC2d>, <theS>, <theF>, <theL> are
+ //! correspondently 3d curve of edge, 2d curve on surface <theS> and
+ //! rang of edge
+ //! If calculated tolerance is more then current edge tolerance, edge is updated.
+ //! Method returns actual tolerance of edge
+ Standard_EXPORT static Standard_Real EvalAndUpdateTol(const TopoDS_Edge& theE,
+ const Handle(Geom_Curve)& theC3d,
+ const Handle(Geom2d_Curve) theC2d,
+ const Handle(Geom_Surface)& theS,
+ const Standard_Real theF,
+ const Standard_Real theL);
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
-
+#include <BRep_Builder.hxx>
+//
static void GeomLib_ChangeUBounds(Handle(Geom_BSplineSurface)& aSurface,
const Standard_Real newU1,
const Standard_Real newU2)
(st == STANDARD_TYPE(Geom2d_BezierCurve))) {
if(isConvert2d) {
Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
+ Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+ if(newTol > Tol)
+ {
+ Tol = newTol;
+ myUpdatedEdges.Append(newE);
+ }
return Standard_True;
}
return Standard_False;
ProjLib_ComputeApprox ProjOnCurve(G3dAHC,GAHS,Tol);
if(ProjOnCurve.BSpline().IsNull()) {
Curve2d = Geom2dConvert::CurveToBSplineCurve(ProjOnCurve.Bezier());
+ Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+ if(newTol > Tol)
+ {
+ Tol = newTol;
+ myUpdatedEdges.Append(newE);
+ }
return Standard_True;
}
Curve2d = ProjOnCurve.BSpline();
+ Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+ if(newTol > Tol)
+ {
+ Tol = newTol;
+ myUpdatedEdges.Append(newE);
+ }
return Standard_True;
}
GeomAdaptor_Surface GAS(S,Uinf-u,Usup+u,Vinf-v,Vsup+v);
if(ProjOnCurve.IsDone()) {
Curve2d = ProjOnCurve.BSpline();
+ Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+ if(newTol > Tol)
+ {
+ Tol = newTol;
+ myUpdatedEdges.Append(newE);
+ }
return Standard_True;
}
else {
Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
+ Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+ if(newTol > Tol)
+ {
+ Tol = newTol;
+ myUpdatedEdges.Append(newE);
+ }
return Standard_True;
}
}
if(C3d.IsNull()) {
if(isConvert2d) {
Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
+
+ Handle(Geom_Surface) S;
+ if(newF.IsNull())
+ S = BRep_Tool::Surface(F);
+ else
+ S = BRep_Tool::Surface(newF);
+ //
+ Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+ if(newTol > Tol)
+ {
+ Tol = newTol;
+ myUpdatedEdges.Append(newE);
+ }
return Standard_True;
}
return Standard_False;
(st == STANDARD_TYPE(Geom2d_BezierCurve))) {
if(isConvert2d) {
Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
+ Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+ if(newTol > Tol)
+ {
+ Tol = newTol;
+ myUpdatedEdges.Append(newE);
+ }
return Standard_True;
}
return Standard_False;
if(ProjOnCurve.IsDone()) {
Curve2d = ProjOnCurve.BSpline();
mylcu.Append(ProjOnCurve.Curve2d());
+ Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+ if(newTol > Tol)
+ {
+ Tol = newTol;
+ myUpdatedEdges.Append(newE);
+ }
return Standard_True;
}
else {
Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
+ Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+ if(newTol > Tol)
+ {
+ Tol = newTol;
+ myUpdatedEdges.Append(newE);
+ }
mylcu.Append(C2dBis);
return Standard_True;
}
}
+//=======================================================================
+//function : GetUpdatedEdges
+//purpose :
+//=======================================================================
+const TopTools_ListOfShape&
+ BRepTools_NurbsConvertModification::GetUpdatedEdges() const
+{
+ return myUpdatedEdges;
+}
\ No newline at end of file
//! (resp. <F2>).
Standard_EXPORT GeomAbs_Shape Continuity (const TopoDS_Edge& E, const TopoDS_Face& F1, const TopoDS_Face& F2, const TopoDS_Edge& NewE, const TopoDS_Face& NewF1, const TopoDS_Face& NewF2);
+ Standard_EXPORT const TopTools_ListOfShape& GetUpdatedEdges() const;
TopTools_ListOfShape myled;
TColStd_ListOfTransient mylcu;
TColStd_IndexedDataMapOfTransientTransient myMap;
+ TopTools_ListOfShape myUpdatedEdges;
};
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <GeomLib_CheckCurveOnSurface.hxx>
-#include <BRepLib.hxx>
-//
-static Standard_Real EvalTol(const Handle(Geom_Curve)& C3d,
- const Handle(Geom2d_Curve) C2d,
- const Handle(Geom_Surface)& S,
- const Standard_Real f,
- const Standard_Real l)
-{
- Standard_Real first = f, last = l;
- //Set first, last to avoid ErrosStatus = 2 because of
- //too strong checking of limits in class CheckCurveOnSurface
- //
- if(!C3d->IsPeriodic())
- {
- first = Max(first, C3d->FirstParameter());
- last = Min(last, C3d->LastParameter());
- }
- if(!C2d->IsPeriodic())
- {
- first = Max(first, C2d->FirstParameter());
- last = Min(last, C2d->LastParameter());
- }
-
- GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
- CT.Perform(C2d);
- if(CT.IsDone())
- {
- return CT.MaxDistance();
- }
- else
- {
- if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 &&
- (C3d->IsPeriodic() || C2d->IsPeriodic())))
- {
- //Try to estimate by sample points
- Standard_Integer nbint = 22;
- Standard_Real dt = (last - first) / nbint;
- dt = Max(dt, Precision::Confusion());
- Standard_Real d, dmax = 0.;
- gp_Pnt2d aP2d;
- gp_Pnt aPC, aPS;
- Standard_Integer cnt = 0;
- Standard_Real t = first;
- for(; t <= last; t += dt)
- {
- cnt++;
- C2d->D0(t, aP2d);
- C3d->D0(t, aPC);
- S->D0(aP2d.X(), aP2d.Y(), aPS);
- d = aPS.SquareDistance(aPC);
- if(d > dmax)
- {
- dmax = d;
- }
- }
- if(cnt < nbint + 1)
- {
- t = last;
- C2d->D0(t, aP2d);
- C3d->D0(t, aPC);
- S->D0(aP2d.X(), aP2d.Y(), aPS);
- d = aPS.SquareDistance(aPC);
- if(d > dmax)
- {
- dmax = d;
- }
- }
-
- dmax = 1.2 * Sqrt(dmax);
- return dmax;
- }
- else
- {
- return 0.;
- }
- }
-}
//=======================================================================
//function : Draft_Modification
}
//
Handle(Geom_Curve) aC3d = BRep_Tool::Curve(NewE, Fp, Lp);
- Standard_Real newtol = EvalTol(aC3d, C, SB, Fp, Lp);
- if(newtol > Tol)
- {
- Tol = newtol;
- BRep_Builder B;
- B.UpdateEdge(NewE, newtol);
- }
+ Tol = BRepTools::EvalAndUpdateTol(NewE,aC3d, C, SB, Fp, Lp);
return Standard_True;
}
--- /dev/null
+puts "============"
+puts "OCC24890"
+puts "============"
+puts ""
+##############################################################
+## Result of uniform scaling is invalid
+##############################################################
+
+restore [locate_data_file bug24890_f0.brep] f0
+
+nurbsconvert result f0
+
+checkshape result
+
+set 3dviewer 1