bounding box for Loop

This commit is contained in:
Matthias Hochsteger 2020-10-14 17:13:17 +02:00
parent 476a4c350c
commit 7b8b3b03ca
2 changed files with 35 additions and 22 deletions

View File

@ -670,13 +670,16 @@ void AddIntersectionPoint(Edge edgeP, Edge edgeQ, IntersectionType i, double alp
} }
} }
void ComputeIntersections(Solid2d & s1, Solid2d & s2)
void ComputeIntersections(Solid2d & sp, Solid2d & sq)
{ {
static Timer tall("ComputeIntersections"); RegionTimer rtall(tall); static Timer tall("ComputeIntersections"); RegionTimer rtall(tall);
auto & PP = sp.polys; static Timer t_tree("build search trees");
auto & QQ = sq.polys; static Timer t_intersect("find intersections");
static Timer t_split("split splines");
auto & PP = s1.polys;
auto & QQ = s2.polys;
t_intersect.Start();
for (Loop& P : PP) for (Loop& P : PP)
for (Edge edgeP : P.Edges(SOURCE)) for (Edge edgeP : P.Edges(SOURCE))
for (Loop& Q : QQ) for (Loop& Q : QQ)
@ -716,6 +719,9 @@ void ComputeIntersections(Solid2d & sp, Solid2d & sq)
} }
} }
} }
t_intersect.Stop();
RegionTimer rt_split(t_split);
// Split splines at new vertices // Split splines at new vertices
auto split_spline_at_vertex = [](Vertex *v) auto split_spline_at_vertex = [](Vertex *v)
@ -1351,25 +1357,21 @@ Solid2d ClipSolids ( Solid2d && s1, Solid2d && s2, char op)
res_polys.SetSize(0); res_polys.SetSize(0);
t02.Start(); t02.Start();
netgen::Box<2> s1_box(netgen::Box<2>::EMPTY_BOX); auto s1_box = s1.GetBoundingBox();
netgen::BoxTree <2, int> tree1(s1.GetBoundingBox()); netgen::BoxTree <2, int> tree1(s1_box);
for(auto li : IntRange(n1)) for(auto li : IntRange(n1))
{ {
auto box = s1.polys[li].GetBoundingBox(); auto box = s1.polys[li].GetBoundingBox();
s1_box.Add(box.PMin());
s1_box.Add(box.PMax());
tree1.Insert(box, li); tree1.Insert(box, li);
} }
netgen::Box<2> s2_box(netgen::Box<2>::EMPTY_BOX); auto s2_box = s2.GetBoundingBox();
netgen::BoxTree <2, int> tree2(s2.GetBoundingBox()); netgen::BoxTree <2, int> tree2(s2.GetBoundingBox());
for(auto li : IntRange(n2)) for(auto li : IntRange(n2))
{ {
auto box = s2.polys[li].GetBoundingBox(); auto box = s2.polys[li].GetBoundingBox();
s2_box.Add(box.PMin());
s2_box.Add(box.PMax());
tree2.Insert(box, li); tree2.Insert(box, li);
} }
t02.Stop(); t02.Stop();
@ -1529,15 +1531,6 @@ bool Loop :: IsInside( Point<2> r ) const
return ( (w % 2) != 0 ); return ( (w % 2) != 0 );
} }
netgen::Box<2> Loop :: GetBoundingBox() const
{
// static Timer tall("Loop::GetBoundingBox"); RegionTimer rtall(tall);
netgen::Box<2> box(netgen::Box<2>::EMPTY_BOX);
for(auto v : Vertices(ALL))
box.Add(*v);
return box;
}
Solid2d :: Solid2d(const Array<std::variant<Point<2>, EdgeInfo>> & points, string name_, string bc) Solid2d :: Solid2d(const Array<std::variant<Point<2>, EdgeInfo>> & points, string name_, string bc)
: name(name_) : name(name_)
@ -1729,6 +1722,7 @@ shared_ptr<netgen::SplineGeometry2d> CSG2d :: GenerateSplineGeometry()
static Timer tall("CSG2d - GenerateSplineGeometry()"); static Timer tall("CSG2d - GenerateSplineGeometry()");
static Timer t_points("add points"); static Timer t_points("add points");
static Timer t_segments_map("build segments map"); static Timer t_segments_map("build segments map");
static Timer t_is_inside("is inside check");
static Timer t_segments("add segments"); static Timer t_segments("add segments");
static Timer t_intersections("add intersections"); static Timer t_intersections("add intersections");
RegionTimer rt(tall); RegionTimer rt(tall);
@ -1861,6 +1855,7 @@ shared_ptr<netgen::SplineGeometry2d> CSG2d :: GenerateSplineGeometry()
if(first) if(first)
{ {
RegionTimer rt_inside(t_is_inside);
is_poly_left_inside = s.IsLeftInside(p0); is_poly_left_inside = s.IsLeftInside(p0);
is_poly_right_inside = s.IsRightInside(p0); is_poly_right_inside = s.IsRightInside(p0);
first = true; first = true;

View File

@ -12,6 +12,7 @@ using namespace ngcore;
using netgen::Point; using netgen::Point;
using netgen::Vec; using netgen::Vec;
using Spline = SplineSeg3<2>; using Spline = SplineSeg3<2>;
using netgen::Box;
inline double Area(const Point<2>& P, const Point<2>& Q, const Point<2>& R) inline double Area(const Point<2>& P, const Point<2>& Q, const Point<2>& R)
{ {
@ -395,6 +396,7 @@ inline int CalcSide( const Point<2> & p0, const Point<2> & p1, const Point<2> &
struct Loop struct Loop
{ {
unique_ptr<Vertex> first = nullptr; unique_ptr<Vertex> first = nullptr;
unique_ptr<Box<2>> bbox = nullptr;
Loop() = default; Loop() = default;
@ -440,6 +442,7 @@ struct Loop
first = std::move(new_verts[0]); first = std::move(new_verts[0]);
} }
bbox = nullptr;
return *this; return *this;
} }
@ -454,6 +457,8 @@ struct Loop
vnew.info = v.info; vnew.info = v.info;
if(v.spline) if(v.spline)
vnew.spline = *v.spline; vnew.spline = *v.spline;
if(bbox)
bbox->Add(v);
return vnew; return vnew;
} }
@ -474,6 +479,8 @@ struct Loop
vnew->is_source = source; vnew->is_source = source;
// cout << "size after " << Size() << endl; // cout << "size after " << Size() << endl;
if(bbox)
bbox->Add(p);
return *vnew; return *vnew;
} }
@ -485,6 +492,7 @@ struct Loop
first = std::move(v->pnext); first = std::move(v->pnext);
else else
v->prev->pnext = std::move(v->pnext); v->prev->pnext = std::move(v->pnext);
bbox.reset();
} }
bool IsInside( Point<2> r ) const; bool IsInside( Point<2> r ) const;
@ -594,7 +602,17 @@ struct Loop
return cnt; return cnt;
} }
netgen::Box<2> GetBoundingBox() const; const Box<2> & GetBoundingBox()
{
if(bbox==nullptr)
{
static Timer tall("Loop::GetBoundingBox"); RegionTimer rt(tall);
bbox = make_unique<Box<2>>(Box<2>::EMPTY_BOX);
for(auto v : Vertices(ALL))
bbox->Add(*v);
}
return *bbox;
}
}; };
@ -679,7 +697,7 @@ struct Solid2d
return *this; return *this;
} }
netgen::Box<2> GetBoundingBox() const; Box<2> GetBoundingBox() const;
}; };