Don't consider arc center point for bounding box calculation.

This commit is contained in:
EvilSpirit 2016-10-30 17:26:31 +07:00 committed by whitequark
parent cdd6174cfa
commit 600c39db91
14 changed files with 42 additions and 20 deletions

View File

@ -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

View File

@ -108,6 +108,11 @@ void Request::Generate(IdList<Entity,hEntity> *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;

View File

@ -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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB