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
#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,
}
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();
}
}
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);
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;
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());
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 );
#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
//=======================================================================
//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;
gac.Load(c2d,cf,cl);
BndLib_Add2dCurve::Add(gac,::Precision::Confusion(),box);
boxes.Bind(E,box);
+ aTotalBox.Add (box);
}
}
- return Standard_True;
+ return aTotalBox;
}
// 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;
}
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
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);
}
}
--- /dev/null
+puts "============"
+puts "OCC24596"
+puts "============"
+puts ""
+###############################
+## Slow import of IGES data
+###############################
+
+pload QAcommands
+
+cpulimit 2000
+
+if { [regexp {Debug mode} [dversion]] } {
+ if { [regexp {Windows} [dversion]] } {
+ set max_time 900
+ set max_time2 500
+ } else {
+ set max_time 1200
+ set max_time2 800
+ }
+} else {
+ if { [regexp {Windows} [dversion]] } {
+ set max_time 900
+ set max_time2 500
+ } else {
+ set max_time 1200
+ set max_time2 800
+ }
+}
+
+# 1 - igesread
+dchrono h reset
+dchrono h start
+
+igesread [locate_data_file 100B_Nosecone_with_Triangular_FSS.igs] a 43479
+
+dchrono h stop
+set q [dchrono h show]
+
+regexp {CPU user time: ([-0-9.+eE]+) seconds} $q full z
+puts "$z"
+
+if { $z > ${max_time} } {
+ puts "Elapsed time of igesread is more than ${max_time} seconds - Faulty"
+} else {
+ puts "Elapsed time of igesread is less than ${max_time} seconds - OK"
+}
+
+# 2 - checkshape
+dchrono h2 reset
+dchrono h2 start
+
+checkshape a_1
+
+dchrono h2 stop
+set q2 [dchrono h2 show]
+
+regexp {CPU user time: ([-0-9.+eE]+) seconds} $q2 full z2
+puts "$z2"
+
+if { $z2 > ${max_time2} } {
+ puts "Elapsed time of checkshape is more than ${max_time2} seconds - Faulty"
+} else {
+ puts "Elapsed time of checkshape is less than ${max_time2} seconds - OK"
+}
--- /dev/null
+puts "============"
+puts "OCC24596"
+puts "============"
+puts ""
+###############################
+## Slow import of IGES data
+###############################
+
+pload QAcommands
+
+cpulimit 2000
+
+if { [regexp {Debug mode} [dversion]] } {
+ if { [regexp {Windows} [dversion]] } {
+ set max_time 900
+ set max_time2 500
+ } else {
+ set max_time 1200
+ set max_time2 800
+ }
+} else {
+ if { [regexp {Windows} [dversion]] } {
+ set max_time 900
+ set max_time2 500
+ } else {
+ set max_time 1200
+ set max_time2 800
+ }
+}
+
+# 1 - igesread
+dchrono h reset
+dchrono h start
+
+igesread [locate_data_file 100B_Nosecone_with_Triangular_FSS.igs] b 86884
+
+dchrono h stop
+set q [dchrono h show]
+
+regexp {CPU user time: ([-0-9.+eE]+) seconds} $q full z
+puts "$z"
+
+if { $z > ${max_time} } {
+ puts "Elapsed time is more than ${max_time} seconds - Faulty"
+} else {
+ puts "Elapsed time is less than ${max_time} seconds - OK"
+}
+
+# 2 - checkshape
+dchrono h2 reset
+dchrono h2 start
+
+checkshape b_1
+
+dchrono h2 stop
+set q2 [dchrono h2 show]
+
+regexp {CPU user time: ([-0-9.+eE]+) seconds} $q2 full z2
+puts "$z2"
+
+if { $z2 > ${max_time2} } {
+ puts "Elapsed time of checkshape is more than ${max_time2} seconds - Faulty"
+} else {
+ puts "Elapsed time of checkshape is less than ${max_time2} seconds - OK"
+}