mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0024596: Slow import of IGES data
Part 1: Speed up of import functionality. Correction in ShapeFix_IntersectionTool::FixIntersectingWires() - preliminary construction of ShapeAnalysis_Surface tool for the whole face; computation of 2d bounding boxes for edges and wires before intersection checking. Part 2: Speed up of check shape. Correction in BRepCheck_Face::IntersectWires() in the same way: preliminary computation of 2d boxes for edges and wires in order to reduce the number of calls of intersection tool for pair of wires. Test cases for issue CR24596
This commit is contained in:
@@ -63,10 +63,15 @@
|
||||
#include <IntRes2d_IntersectionSegment.hxx>
|
||||
#include <BRepAdaptor_HSurface.hxx>
|
||||
|
||||
#include <TopTools_OrientedShapeMapHasher.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
|
||||
typedef NCollection_DataMap<TopoDS_Shape, Bnd_Box2d, TopTools_OrientedShapeMapHasher> DataMapOfShapeBox2d;
|
||||
|
||||
static Standard_Boolean Intersect(const TopoDS_Wire&,
|
||||
const TopoDS_Wire&,
|
||||
const TopoDS_Face&);
|
||||
const TopoDS_Face&,
|
||||
const DataMapOfShapeBox2d&);
|
||||
|
||||
|
||||
static Standard_Boolean IsInside(const TopoDS_Wire& wir,
|
||||
@@ -201,7 +206,36 @@ BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
|
||||
}
|
||||
exp1.Next();
|
||||
}
|
||||
|
||||
|
||||
Geom2dAdaptor_Curve aC;
|
||||
Standard_Real aFirst, aLast;
|
||||
DataMapOfShapeBox2d aMapShapeBox2d;
|
||||
for (exp1.Init (myShape, TopAbs_WIRE); exp1.More(); exp1.Next())
|
||||
{
|
||||
const TopoDS_Wire& aWire = TopoDS::Wire (exp1.Current());
|
||||
// create 2d boxes for all edges from wire
|
||||
Bnd_Box2d aBoxW;
|
||||
for (exp2.Init (aWire, TopAbs_EDGE); exp2.More(); exp2.Next())
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge (exp2.Current());
|
||||
aC.Load (BRep_Tool::CurveOnSurface (anEdge, TopoDS::Face (myShape), aFirst, aLast));
|
||||
// To avoid exeption in Segment if C1 is BSpline
|
||||
if (aC.FirstParameter() > aFirst)
|
||||
{
|
||||
aFirst = aC.FirstParameter();
|
||||
}
|
||||
if (aC.LastParameter() < aLast)
|
||||
{
|
||||
aLast = aC.LastParameter();
|
||||
}
|
||||
Bnd_Box2d aBoxE;
|
||||
BndLib_Add2dCurve::Add (aC, aFirst, aLast, 0., aBoxE);
|
||||
aMapShapeBox2d.Bind (anEdge, aBoxE);
|
||||
aBoxW.Add (aBoxE);
|
||||
}
|
||||
aMapShapeBox2d.Bind (aWire, aBoxW);
|
||||
}
|
||||
|
||||
Standard_Integer Nbwire, Index,Indexbis;
|
||||
Nbwire = myMapImb.Extent();
|
||||
|
||||
@@ -215,10 +249,24 @@ BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
|
||||
}
|
||||
}
|
||||
TopoDS_Wire wir1 = TopoDS::Wire(exp1.Current());
|
||||
// to reduce the number of calls Intersect(wir1,wir2)
|
||||
Bnd_Box2d aBox1, aBox2;
|
||||
if (aMapShapeBox2d.IsBound (wir1))
|
||||
{
|
||||
aBox1 = aMapShapeBox2d (wir1);
|
||||
}
|
||||
exp1.Next();
|
||||
for (; exp1.More(); exp1.Next()) {
|
||||
const TopoDS_Wire& wir2 = TopoDS::Wire(exp1.Current());
|
||||
if (Intersect(wir1,wir2,TopoDS::Face(myShape))) {
|
||||
if (aMapShapeBox2d.IsBound (wir2))
|
||||
{
|
||||
aBox2 = aMapShapeBox2d (wir2);
|
||||
}
|
||||
if (!aBox1.IsVoid() && !aBox2.IsVoid() && aBox1.IsOut (aBox2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (Intersect(wir1,wir2,TopoDS::Face(myShape), aMapShapeBox2d)) {
|
||||
myIntres = BRepCheck_IntersectingWires;
|
||||
if (Update) {
|
||||
BRepCheck::Add(myMap(myShape),myIntres);
|
||||
@@ -503,7 +551,8 @@ Standard_Boolean BRepCheck_Face::GeometricControls() const
|
||||
|
||||
static Standard_Boolean Intersect(const TopoDS_Wire& wir1,
|
||||
const TopoDS_Wire& wir2,
|
||||
const TopoDS_Face& F)
|
||||
const TopoDS_Face& F,
|
||||
const DataMapOfShapeBox2d& theMapEdgeBox)
|
||||
{
|
||||
Standard_Real Inter2dTol = 1.e-10;
|
||||
TopExp_Explorer exp1,exp2;
|
||||
@@ -551,11 +600,15 @@ static Standard_Boolean Intersect(const TopoDS_Wire& wir1,
|
||||
if(C1.FirstParameter() > first1) first1 = C1.FirstParameter();
|
||||
if(C1.LastParameter() < last1 ) last1 = C1.LastParameter();
|
||||
|
||||
BRep_Tool::UVPoints(edg1,F,pfirst1,plast1);
|
||||
myDomain1.SetValues( pfirst1, first1, Inter2dTol, plast1, last1, Inter2dTol );
|
||||
Box1.SetVoid();
|
||||
BndLib_Add2dCurve::Add( C1, first1, last1, 0., Box1 );
|
||||
|
||||
if (theMapEdgeBox.IsBound (edg1))
|
||||
{
|
||||
Box1 = theMapEdgeBox (edg1);
|
||||
}
|
||||
if (Box1.IsVoid())
|
||||
{
|
||||
BndLib_Add2dCurve::Add( C1, first1, last1, 0., Box1 );
|
||||
}
|
||||
for (exp2.Init(wir2,TopAbs_EDGE); exp2.More(); exp2.Next())
|
||||
{
|
||||
const TopoDS_Edge& edg2 = TopoDS::Edge(exp2.Current());
|
||||
@@ -567,10 +620,19 @@ static Standard_Boolean Intersect(const TopoDS_Wire& wir1,
|
||||
if(C2.FirstParameter() > first2) first2 = C2.FirstParameter();
|
||||
if(C2.LastParameter() < last2 ) last2 = C2.LastParameter();
|
||||
|
||||
Box2.SetVoid();
|
||||
BndLib_Add2dCurve::Add( C2, first2, last2, 0., Box2 );
|
||||
Box2.SetVoid();
|
||||
if (theMapEdgeBox.IsBound (edg2))
|
||||
{
|
||||
Box2 = theMapEdgeBox (edg2);
|
||||
}
|
||||
if (Box2.IsVoid())
|
||||
{
|
||||
BndLib_Add2dCurve::Add( C2, first2, last2, 0., Box2 );
|
||||
}
|
||||
if (! Box1.IsOut( Box2 ))
|
||||
{
|
||||
BRep_Tool::UVPoints(edg1,F,pfirst1,plast1);
|
||||
myDomain1.SetValues( pfirst1, first1, Inter2dTol, plast1, last1, Inter2dTol );
|
||||
BRep_Tool::UVPoints(edg2,F,pfirst2,plast2);
|
||||
myDomain2.SetValues( pfirst2, first2, Inter2dTol, plast2, last2, Inter2dTol );
|
||||
Inter.Perform( C1, myDomain1, C2, myDomain2, Inter2dTol, Inter2dTol );
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopTools_SequenceOfShape.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
|
||||
//gka 06.09.04 BUG 6555 shape is modified always independently either intersection was fixed or not
|
||||
//=======================================================================
|
||||
@@ -684,11 +685,12 @@ Standard_Boolean ShapeFix_IntersectionTool::UnionVertexes(const Handle(ShapeExte
|
||||
//function : CreateBoxes2d
|
||||
//purpose : auxilary
|
||||
//=======================================================================
|
||||
static Standard_Boolean CreateBoxes2d(const Handle(ShapeExtend_WireData)& sewd,
|
||||
static Bnd_Box2d CreateBoxes2d(const Handle(ShapeExtend_WireData)& sewd,
|
||||
const TopoDS_Face& face,
|
||||
ShapeFix_DataMapOfShapeBox2d& boxes)
|
||||
{
|
||||
// create box2d for edges from wire
|
||||
Bnd_Box2d aTotalBox;
|
||||
TopLoc_Location L;
|
||||
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face,L);
|
||||
Handle(Geom2d_Curve) c2d;
|
||||
@@ -710,9 +712,10 @@ static Standard_Boolean CreateBoxes2d(const Handle(ShapeExtend_WireData)& sewd,
|
||||
gac.Load(c2d,cf,cl);
|
||||
BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
|
||||
boxes.Bind(E,box);
|
||||
aTotalBox.Add (box);
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
return aTotalBox;
|
||||
}
|
||||
|
||||
|
||||
@@ -832,7 +835,7 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
|
||||
|
||||
// step 2 : intersection of non-adjacent edges
|
||||
ShapeFix_DataMapOfShapeBox2d boxes;
|
||||
CreateBoxes2d(sewd,face,boxes);
|
||||
Bnd_Box2d aTotalBox = CreateBoxes2d(sewd,face,boxes);
|
||||
Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
|
||||
|
||||
NbSplit=0;
|
||||
@@ -1469,19 +1472,36 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
|
||||
}
|
||||
Standard_Boolean isDone = Standard_False; //gka 06.09.04
|
||||
ShapeAnalysis_Edge sae;
|
||||
Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface (BRep_Tool::Surface (face));
|
||||
|
||||
// precompute edge boxes for all wires
|
||||
NCollection_Sequence<ShapeFix_DataMapOfShapeBox2d> aSeqWirEdgeBoxes;
|
||||
NCollection_Sequence<Bnd_Box2d> aSeqWirBoxes;
|
||||
for (Standard_Integer n = 1; n <= SeqWir.Length(); n++)
|
||||
{
|
||||
const TopoDS_Wire& aWire = TopoDS::Wire (SeqWir.Value (n));
|
||||
Handle(ShapeExtend_WireData) aSewd = new ShapeExtend_WireData (aWire);
|
||||
ShapeFix_DataMapOfShapeBox2d aBoxes;
|
||||
Bnd_Box2d aTotalBox = CreateBoxes2d (aSewd, face, aBoxes);
|
||||
aSeqWirEdgeBoxes.Append (aBoxes);
|
||||
aSeqWirBoxes.Append (aTotalBox);
|
||||
}
|
||||
|
||||
for(Standard_Integer n1=1; n1<=SeqWir.Length()-1; n1++) {
|
||||
TopoDS_Wire wire1 = TopoDS::Wire(SeqWir.Value(n1));
|
||||
Handle(ShapeExtend_WireData) sewd1 = new ShapeExtend_WireData(wire1);
|
||||
ShapeFix_DataMapOfShapeBox2d& boxes1 = aSeqWirEdgeBoxes.ChangeValue (n1);
|
||||
Bnd_Box2d aBox1 = aSeqWirBoxes (n1);
|
||||
for(Standard_Integer n2=n1+1; n2<=SeqWir.Length(); n2++) {
|
||||
TopoDS_Wire wire2 = TopoDS::Wire(SeqWir.Value(n2));
|
||||
Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData(wire2);
|
||||
ShapeFix_DataMapOfShapeBox2d& boxes2 = aSeqWirEdgeBoxes.ChangeValue (n2);
|
||||
Bnd_Box2d aBox2 = aSeqWirBoxes (n2);
|
||||
if (!aBox1.IsVoid() && !aBox2.IsVoid() && aBox1.IsOut (aBox2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// detect possible intersections:
|
||||
ShapeFix_DataMapOfShapeBox2d boxes1,boxes2;
|
||||
CreateBoxes2d(sewd1,face,boxes1);
|
||||
CreateBoxes2d(sewd2,face,boxes2);
|
||||
Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
|
||||
|
||||
Standard_Integer NbModif=0;
|
||||
Standard_Integer nbReplaced =0;//gka 06.09.04
|
||||
Standard_Boolean hasModifWire = Standard_False; //gka 06.09.04
|
||||
@@ -1909,9 +1929,17 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
|
||||
SeqWir.SetValue(n1,sewd1->Wire());
|
||||
myContext->Replace( wire1, sewd1->Wire() );
|
||||
wire1 = sewd1->Wire();
|
||||
//recompute boxes for wire1
|
||||
boxes1.Clear();
|
||||
Bnd_Box2d aNewBox1 = CreateBoxes2d (sewd1, face, boxes1);
|
||||
aSeqWirBoxes.SetValue (n1, aNewBox1);
|
||||
SeqWir.SetValue(n2,sewd2->Wire());
|
||||
myContext->Replace( wire2, sewd2->Wire() );
|
||||
wire2 = sewd2->Wire();
|
||||
//recompute boxes for wire2
|
||||
boxes2.Clear();
|
||||
Bnd_Box2d aNewBox2 = CreateBoxes2d (sewd2, face, boxes2);
|
||||
aSeqWirBoxes.SetValue (n2, aNewBox2);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user