diff --git a/CHANGELOG.md b/CHANGELOG.md index c828b14..a0beb5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ New sketch features: boolean operation, to increase performance. * Translate and rotate groups can create n-dimensional arrays using the "difference" and "assembly" boolean operations. + * Irrelevant points (e.g. arc center point) are not counted when estimating + the bounding box used to compute chord tolerance. New export/import features: * Three.js: allow configuring projection for exported model, and initially diff --git a/src/request.cpp b/src/request.cpp index c0065ef..bfef176 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -108,6 +108,11 @@ void Request::Generate(IdList *entity, p.h = h.entity(i+((et != (Entity::Type)0) ? 1 : 0)); p.group = group; p.style = style; + if(type == Request::Type::ARC_OF_CIRCLE && i == 0) { + // mark arc center point as construction, since it shouldn't be included + // in bounding box calculation + p.construction = true; + } if(workplane.v == Entity::FREE_IN_3D.v) { p.type = Entity::Type::POINT_IN_3D; diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 587ccaa..e4dc720 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -859,34 +859,49 @@ void Sketch::Clear() { BBox Sketch::CalculateEntityBBox(bool includingInvisible) { BBox box = {}; bool first = true; - for(int i = 0; i < entity.n; i++) { - Entity *e = (Entity *)&entity.elem[i]; - if(!(e->IsVisible() || includingInvisible)) continue; - - Vector point; - double r = 0.0; - if(e->IsPoint()) { - point = e->PointGetNum(); - } else { - switch(e->type) { - case Entity::Type::ARC_OF_CIRCLE: - case Entity::Type::CIRCLE: - r = e->CircleGetRadiusNum(); - point = GetEntity(e->point[0])->PointGetNum(); - break; - default: continue; - } - } + auto includePoint = [&](const Vector &point) { if(first) { box.minp = point; box.maxp = point; - box.Include(point, r); first = false; } else { - box.Include(point, r); + box.Include(point); + } + }; + + for(const Entity &e : entity) { + if(e.construction) continue; + if(!(includingInvisible || e.IsVisible())) continue; + + if(e.IsPoint()) { + includePoint(e.PointGetNum()); + continue; + } + + switch(e.type) { + // Circles and arcs are special cases. We calculate their bounds + // based on Bezier curve bounds. This is not exact for arcs, + // but the implementation is rather simple. + case Entity::Type::CIRCLE: + case Entity::Type::ARC_OF_CIRCLE: { + SBezierList sbl = {}; + e.GenerateBezierCurves(&sbl); + + for(const SBezier &sb : sbl.l) { + for(int j = 0; j <= sb.deg; j++) { + includePoint(sb.ctrl[j]); + } + } + sbl.Clear(); + continue; + } + + default: + continue; } } + return box; } diff --git a/test/constraint/arc_line_tangent/normal.slvs b/test/constraint/arc_line_tangent/normal.slvs index 86a7d82..2f92e3b 100644 Binary files a/test/constraint/arc_line_tangent/normal.slvs and b/test/constraint/arc_line_tangent/normal.slvs differ diff --git a/test/constraint/curve_curve_tangent/arc_arc.slvs b/test/constraint/curve_curve_tangent/arc_arc.slvs index 995d11e..c18c342 100644 Binary files a/test/constraint/curve_curve_tangent/arc_arc.slvs and b/test/constraint/curve_curve_tangent/arc_arc.slvs differ diff --git a/test/constraint/curve_curve_tangent/arc_cubic.slvs b/test/constraint/curve_curve_tangent/arc_cubic.slvs index 554b38a..47ff668 100644 Binary files a/test/constraint/curve_curve_tangent/arc_cubic.slvs and b/test/constraint/curve_curve_tangent/arc_cubic.slvs differ diff --git a/test/constraint/equal_line_arc_len/normal.slvs b/test/constraint/equal_line_arc_len/normal.slvs index 733864b..c53cbc7 100644 Binary files a/test/constraint/equal_line_arc_len/normal.slvs and b/test/constraint/equal_line_arc_len/normal.slvs differ diff --git a/test/constraint/pt_face_distance/normal.png b/test/constraint/pt_face_distance/normal.png index 7379577..7173202 100644 Binary files a/test/constraint/pt_face_distance/normal.png and b/test/constraint/pt_face_distance/normal.png differ diff --git a/test/constraint/pt_face_distance/normal.slvs b/test/constraint/pt_face_distance/normal.slvs index 2e4195e..07f96ed 100644 Binary files a/test/constraint/pt_face_distance/normal.slvs and b/test/constraint/pt_face_distance/normal.slvs differ diff --git a/test/constraint/pt_face_distance/reference.png b/test/constraint/pt_face_distance/reference.png index 8b06408..4b813f8 100644 Binary files a/test/constraint/pt_face_distance/reference.png and b/test/constraint/pt_face_distance/reference.png differ diff --git a/test/constraint/pt_face_distance/reference.slvs b/test/constraint/pt_face_distance/reference.slvs index a57b808..f3b046c 100644 Binary files a/test/constraint/pt_face_distance/reference.slvs and b/test/constraint/pt_face_distance/reference.slvs differ diff --git a/test/constraint/pt_on_face/normal.png b/test/constraint/pt_on_face/normal.png index 4722a97..1258dca 100644 Binary files a/test/constraint/pt_on_face/normal.png and b/test/constraint/pt_on_face/normal.png differ diff --git a/test/constraint/pt_on_face/normal.slvs b/test/constraint/pt_on_face/normal.slvs index 03ee428..499b14f 100644 Binary files a/test/constraint/pt_on_face/normal.slvs and b/test/constraint/pt_on_face/normal.slvs differ diff --git a/test/request/arc_of_circle/normal.slvs b/test/request/arc_of_circle/normal.slvs index 6f92e0e..c2ca334 100644 Binary files a/test/request/arc_of_circle/normal.slvs and b/test/request/arc_of_circle/normal.slvs differ