1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0031464: BRepOffsetAPI_MakeFilling algorithm increases tolerances of vertices in input edges

Modify history in BRepFill_Filling: now vertices are also stored in the map.
This commit is contained in:
jgv 2020-03-31 18:18:14 +03:00 committed by jfa
parent 4c0aa1bc46
commit e5f648be49
4 changed files with 188 additions and 112 deletions

View File

@ -31,6 +31,7 @@
#include <BRepFill_FaceAndOrder.hxx>
#include <BRepFill_Filling.hxx>
#include <BRepLib.hxx>
#include <BRepLib_MakeVertex.hxx>
#include <BRepLib_MakeEdge.hxx>
#include <BRepLib_MakeEdge2d.hxx>
#include <BRepLib_MakeFace.hxx>
@ -234,8 +235,6 @@ Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
if (IsBound)
{
myBoundary.Append( EdgeFaceAndOrder );
TopTools_ListOfShape EmptyList;
myOldNewMap.Bind(anEdge, EmptyList);
return myBoundary.Length();
}
else
@ -258,8 +257,6 @@ Standard_Integer BRepFill_Filling::Add( const TopoDS_Edge& anEdge,
if (IsBound)
{
myBoundary.Append( EdgeFaceAndOrder );
TopTools_ListOfShape EmptyList;
myOldNewMap.Bind(anEdge, EmptyList);
return myBoundary.Length();
}
else
@ -460,7 +457,9 @@ void BRepFill_Filling::BuildWires( TopTools_ListOfShape& EdgeList, TopTools_List
aDist < BRep_Tool::Tolerance(V_edge[j]))
{
MW.Add(CurEdge);
myOldNewMap(CurEdge).Append(MW.Edge());
TopoDS_Edge NewEdge = MW.Edge();
myOldNewMap.Bind(CurEdge.Oriented(TopAbs_FORWARD),
NewEdge.Oriented(TopAbs_FORWARD));
EdgeList.Remove(Itl);
found = Standard_True;
break;
@ -704,25 +703,48 @@ void BRepFill_Filling::Build()
{
const TopoDS_Edge& InitEdge = myBoundary(i).myEdge;
TopoDS_Edge anEdge = InitEdge;
if (!myOldNewMap(anEdge).IsEmpty())
anEdge = TopoDS::Edge( myOldNewMap(anEdge).First() );
anEdge.Orientation(TopAbs_FORWARD);
if (myOldNewMap.IsBound(anEdge))
anEdge = TopoDS::Edge(myOldNewMap(anEdge));
Handle(Geom2d_Curve) aCurveOnPlate = CurvesOnPlate->Value(i);
TopoDS_Edge NewEdge = TopoDS::Edge(anEdge.EmptyCopied());
TopoDS_Vertex V1, V2;
TopExp::Vertices(anEdge, V1, V2, Standard_True); //with orientation
BB.UpdateVertex(V1, dmax);
BB.UpdateVertex(V2, dmax);
BB.Add(NewEdge, V1);
BB.Add(NewEdge, V2);
TopoDS_Vertex V1, V2, NewV1, NewV2;
TopExp::Vertices(anEdge, V1, V2);
if (myOldNewMap.IsBound(V1))
NewV1 = TopoDS::Vertex(myOldNewMap(V1));
else
{
gp_Pnt aPnt = BRep_Tool::Pnt(V1);
NewV1 = BRepLib_MakeVertex(aPnt);
BB.UpdateVertex(NewV1, dmax);
}
if (myOldNewMap.IsBound(V2))
NewV2 = TopoDS::Vertex(myOldNewMap(V2));
else
{
gp_Pnt aPnt = BRep_Tool::Pnt(V2);
NewV2 = BRepLib_MakeVertex(aPnt);
BB.UpdateVertex(NewV2, dmax);
}
NewV1.Orientation(TopAbs_FORWARD);
BB.Add(NewEdge, NewV1);
NewV2.Orientation(TopAbs_REVERSED);
BB.Add(NewEdge, NewV2);
TopLoc_Location Loc;
BB.UpdateEdge(NewEdge, aCurveOnPlate, Surface, Loc, dmax);
//BRepLib::SameRange(NewEdge);
BRepLib::SameParameter(NewEdge, dmax, Standard_True);
FinalEdges.Append(NewEdge);
myOldNewMap(InitEdge).Clear();
myOldNewMap(InitEdge).Append(NewEdge);
myOldNewMap.Bind(InitEdge.Oriented(TopAbs_FORWARD), NewEdge.Oriented(TopAbs_FORWARD));
myOldNewMap.Bind(V1.Oriented(TopAbs_FORWARD), NewV1.Oriented(TopAbs_FORWARD));
if (!V1.IsSame(V2))
myOldNewMap.Bind(V2.Oriented(TopAbs_FORWARD), NewV2.Oriented(TopAbs_FORWARD));
}
TopoDS_Wire FinalWire = WireFromList(FinalEdges);

View File

@ -25,7 +25,7 @@
#include <BRepFill_SequenceOfEdgeFaceAndOrder.hxx>
#include <BRepFill_SequenceOfFaceAndOrder.hxx>
#include <GeomPlate_SequenceOfPointConstraint.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopoDS_Face.hxx>
#include <Standard_Real.hxx>
@ -207,7 +207,7 @@ private:
BRepFill_SequenceOfEdgeFaceAndOrder myConstraints;
BRepFill_SequenceOfFaceAndOrder myFreeConstraints;
GeomPlate_SequenceOfPointConstraint myPoints;
TopTools_DataMapOfShapeListOfShape myOldNewMap;
TopTools_DataMapOfShapeShape myOldNewMap;
TopTools_ListOfShape myGenerated;
TopoDS_Face myFace;
TopoDS_Face myInitFace;

View File

@ -97,6 +97,7 @@
#include <Geom2d_TrimmedCurve.hxx>
#include <GeomConvert_ApproxSurface.hxx>
#include <BRepTest_Objects.hxx>
#include <stdio.h>
#include <gp_Pnt.hxx>
@ -452,13 +453,18 @@ static Standard_Integer approxplate (Draw_Interpretor & di,Standard_Integer n,co
static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, const char** a )
{
#ifdef OCCT_DEBUG
// Chronmetrage
// Chronometrage
OSD_Chronometer Chrono;
Chrono.Reset();
Chrono.Start();
#endif
if (n < 7) return 1;
if (n < 7)
{
di.PrintHelp(a[0]);
return 1;
}
Standard_Integer NbBounds = Draw::Atoi( a[2] );
Standard_Integer NbConstraints = Draw::Atoi( a[3] );
Standard_Integer NbPoints = Draw::Atoi( a[4] );
@ -473,8 +479,6 @@ static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, cons
TolCurv,
MaxDeg,
MaxSegments );
//TopoDS_Shape aLocalFace(DBRep::Get( a[5], TopAbs_FACE ) );
//TopoDS_Face InitFace = TopoDS::Face( aLocalFace);
TopoDS_Face InitFace = TopoDS::Face( DBRep::Get(a[5], TopAbs_FACE) );
if (! InitFace.IsNull())
MakeFilling.LoadInitSurface( InitFace );
@ -484,104 +488,94 @@ static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, cons
TopoDS_Face F;
gp_Pnt Point;
Standard_Integer Order;
TopTools_ListOfShape ListForHistory;
for (k = 1; k <= NbBounds; k++)
{
E.Nullify();
F.Nullify();
//TopoDS_Shape aLocalEdge(DBRep::Get( a[i], TopAbs_EDGE ));
//E = TopoDS::Edge(aLocalEdge);
E = TopoDS::Edge( DBRep::Get(a[i], TopAbs_EDGE) );
if (! E.IsNull())
i++;
//aLocalFace = DBRep::Get( a[i], TopAbs_FACE ) ;
//F = TopoDS::Face(aLocalFace);
F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
if (! F.IsNull())
i++;
Order = Draw::Atoi( a[i++] );
if (! E.IsNull() && ! F.IsNull())
MakeFilling.Add( E, F, (GeomAbs_Shape)Order );
else if (E.IsNull())
{
if (F.IsNull())
{
//std::cout<<std::endl<<"Wrong parameters"<<std::endl<<std::endl;
di<<"\nWrong parameters\n\n";
return 1;
}
else
MakeFilling.Add( F, (GeomAbs_Shape)Order );
}
else
MakeFilling.Add( E, (GeomAbs_Shape)Order );
}
for (k = 1; k <= NbConstraints; k++)
{
E.Nullify();
F.Nullify();
//TopoDS_Shape aLocalEdge(DBRep::Get( a[i++], TopAbs_EDGE ));
//E = TopoDS::Edge( aLocalEdge);
E = TopoDS::Edge( DBRep::Get(a[i++], TopAbs_EDGE) );
if (E.IsNull())
{
//std::cout<<"Wrong parameters"<<std::endl;
di<<"Wrong parameters\n";
return 1;
}
//TopoDS_Shape alocalFace(DBRep::Get( a[i], TopAbs_FACE ) );
//F = TopoDS::Face( alocalFace);
F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
if (! F.IsNull())
i++;
Order = Draw::Atoi( a[i++] );
if (F.IsNull())
MakeFilling.Add( E, (GeomAbs_Shape)Order, Standard_False );
else
MakeFilling.Add( E, F, (GeomAbs_Shape)Order, Standard_False );
}
for (k = 1; k <= NbPoints; k++)
{
E.Nullify();
F.Nullify();
E = TopoDS::Edge( DBRep::Get(a[i], TopAbs_EDGE) );
if (! E.IsNull())
i++;
F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
if (! F.IsNull())
i++;
Order = Draw::Atoi( a[i++] );
if (! E.IsNull() && ! F.IsNull())
MakeFilling.Add( E, F, (GeomAbs_Shape)Order );
else if (E.IsNull())
{
if (DrawTrSurf::GetPoint( a[i], Point ))
{
MakeFilling.Add( Point );
i++;
}
if (F.IsNull())
{
di<<"\nWrong parameters\n\n";
return 1;
}
else
{
Standard_Real U = Draw::Atof( a[i++] ), V = Draw::Atof( a[i++] );
//aLocalFace = DBRep::Get( a[i++], TopAbs_FACE );
//F = TopoDS::Face( aLocalFace);
F = TopoDS::Face( DBRep::Get(a[i++], TopAbs_FACE));
if (F.IsNull())
{
//std::cout<<"Wrong parameters"<<std::endl;
di<<"Wrong parameters\n";
return 1;
}
Order = Draw::Atoi( a[i++] );
MakeFilling.Add( U, V, F, (GeomAbs_Shape)Order );
}
MakeFilling.Add( F, (GeomAbs_Shape)Order );
}
else
MakeFilling.Add( E, (GeomAbs_Shape)Order );
//History
if (!E.IsNull())
ListForHistory.Append(E);
}
for (k = 1; k <= NbConstraints; k++)
{
E.Nullify();
F.Nullify();
E = TopoDS::Edge( DBRep::Get(a[i++], TopAbs_EDGE) );
if (E.IsNull())
{
di<<"Wrong parameters\n";
return 1;
}
F = TopoDS::Face( DBRep::Get(a[i], TopAbs_FACE) );
if (! F.IsNull())
i++;
Order = Draw::Atoi( a[i++] );
if (F.IsNull())
MakeFilling.Add( E, (GeomAbs_Shape)Order, Standard_False );
else
MakeFilling.Add( E, F, (GeomAbs_Shape)Order, Standard_False );
}
for (k = 1; k <= NbPoints; k++)
{
if (DrawTrSurf::GetPoint( a[i], Point ))
{
MakeFilling.Add( Point );
i++;
}
else
{
Standard_Real U = Draw::Atof( a[i++] ), V = Draw::Atof( a[i++] );
F = TopoDS::Face( DBRep::Get(a[i++], TopAbs_FACE));
if (F.IsNull())
{
di<<"Wrong parameters\n";
return 1;
}
Order = Draw::Atoi( a[i++] );
MakeFilling.Add( U, V, F, (GeomAbs_Shape)Order );
}
}
MakeFilling.Build();
if (! MakeFilling.IsDone())
{
//std::cout<<"filling failed"<<std::endl;
di<<"filling failed\n";
return 0;
}
{
di<<"filling failed\n";
return 0;
}
Standard_Real dmax = MakeFilling.G0Error(),
angmax = MakeFilling.G1Error(),
curvmax = MakeFilling.G2Error();
//std::cout<<" dist. max = "<<dmax<<" ; angle max = "<<angmax<<" ; diffcurv max = "<<curvmax<<std::endl;
angmax = MakeFilling.G1Error(),
curvmax = MakeFilling.G2Error();
di<<" dist. max = "<<dmax<<" ; angle max = "<<angmax<<" ; diffcurv max = "<<curvmax<<"\n";
TopoDS_Face ResFace= TopoDS::Face( MakeFilling.Shape() );
DBRep::Set( a[1], ResFace );
@ -589,12 +583,14 @@ static Standard_Integer filling( Draw_Interpretor & di, Standard_Integer n, cons
Chrono.Stop();
Standard_Real Tps;
Chrono.Show(Tps);
//std::cout<<"*** FIN DE FILLING ***"<<std::endl;
//std::cout<<"Temps de calcul : "<<Tps<<std::endl;
di<<"*** FIN DE FILLING ***\n";
di<<"Temps de calcul : "<<Tps<<"\n";
#endif
//History
if (BRepTest_Objects::IsHistoryNeeded())
BRepTest_Objects::SetHistory(ListForHistory, MakeFilling);
return 0;
}

View File

@ -0,0 +1,58 @@
puts "============================================================================================="
puts "OCC31464: BRepOffsetAPI_MakeFilling algorithm increases tolerances of vertices in input edges"
puts "============================================================================================="
puts ""
brestore [locate_data_file bug31464.brep] a
set tol [checkmaxtol a]
explode a f
explode a_1 e
filling result 3 0 1 a_1_1 0 a_1_2 0 a_1_4 0 0.0785398166 0.0196349541 a_1 1
savehistory hh
set tol2 [checkmaxtol a]
if { ${tol} != ${tol2}} {
puts "Error: tolerance of input shape changed"
}
generated e2 hh a_1_2
explode a_1_3
generated vv hh a_1_3_1
distmini distvv a_1_3_1 vv
if {[dval distvv_val] > 0.} {
puts "Error: generated vertex is wrong"
}
mkcurve oldc a_1_2
mkcurve newc e2
set log [xdistcc oldc newc -3.92699082e-14 0.0392699082 10]
regexp {Max Distance = +([-0-9.+eE]+)} ${log} full dist
if { [dval dist] != 0. } {
puts "Error: generated edge is wrong"
}
smallview
donly result e2 vv
fit
checkshape result
checknbshapes result -face 1 -wire 1 -edge 3 -vertex 3
set tolres [checkmaxtol result]
if { ${tolres} > 0.0007} {
puts "Error: bad tolerance of result"
}
checkprops result -s 0.00190371
checkview -screenshot -2d -path ${imagedir}/${test_image}.png