mirror of https://github.com/vitalif/openscad
bugfix: don't crash on empty resize(). refactoring: added virtual copy() to geometry, moved resize() to CGAL_Nef_polyhedron. Fixes #862
parent
aadb85d86e
commit
f87ee92755
|
@ -9,6 +9,11 @@ CGAL_Nef_polyhedron::CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p)
|
|||
if (p) p3.reset(p);
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
CGAL_Nef_polyhedron::CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron &src)
|
||||
{
|
||||
if (src.p3) this->p3.reset(new CGAL_Nef_polyhedron3(*src.p3));
|
||||
}
|
||||
|
||||
CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator+=(const CGAL_Nef_polyhedron &other)
|
||||
{
|
||||
|
@ -79,12 +84,46 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() const
|
|||
return ps;
|
||||
}
|
||||
|
||||
/*!
|
||||
Deep copy
|
||||
*/
|
||||
CGAL_Nef_polyhedron *CGAL_Nef_polyhedron::copy() const
|
||||
void CGAL_Nef_polyhedron::resize(Vector3d newsize,
|
||||
const Eigen::Matrix<bool,3,1> &autosize)
|
||||
{
|
||||
CGAL_Nef_polyhedron *copy = new CGAL_Nef_polyhedron(*this);
|
||||
if (copy->p3) copy->p3.reset(new CGAL_Nef_polyhedron3(*copy->p3));
|
||||
return copy;
|
||||
// Based on resize() in Giles Bathgate's RapCAD (but not exactly)
|
||||
if (this->isEmpty()) return;
|
||||
|
||||
CGAL_Iso_cuboid_3 bb = CGALUtils::boundingBox(*this->p3);
|
||||
|
||||
std::vector<NT3> scale, bbox_size;
|
||||
for (unsigned int i=0;i<3;i++) {
|
||||
scale.push_back(NT3(1));
|
||||
bbox_size.push_back(bb.max_coord(i) - bb.min_coord(i));
|
||||
}
|
||||
int newsizemax_index = 0;
|
||||
for (unsigned int i=0;i<this->getDimension();i++) {
|
||||
if (newsize[i]) {
|
||||
if (bbox_size[i] == NT3(0)) {
|
||||
PRINT("WARNING: Resize in direction normal to flat object is not implemented");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
scale[i] = NT3(newsize[i]) / bbox_size[i];
|
||||
}
|
||||
if (newsize[i] > newsize[newsizemax_index]) newsizemax_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
NT3 autoscale = NT3(1);
|
||||
if (newsize[newsizemax_index] != 0) {
|
||||
autoscale = NT3(newsize[newsizemax_index]) / bbox_size[newsizemax_index];
|
||||
}
|
||||
for (unsigned int i=0;i<this->getDimension();i++) {
|
||||
if (autosize[i] && newsize[i]==0) scale[i] = autoscale;
|
||||
}
|
||||
|
||||
Eigen::Matrix4d t;
|
||||
t << CGAL::to_double(scale[0]), 0, 0, 0,
|
||||
0, CGAL::to_double(scale[1]), 0, 0,
|
||||
0, 0, CGAL::to_double(scale[2]), 0,
|
||||
0, 0, 0, 1;
|
||||
|
||||
this->transform(Transform3d(t));
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ class CGAL_Nef_polyhedron : public Geometry
|
|||
{
|
||||
public:
|
||||
CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p = NULL);
|
||||
CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron &src);
|
||||
~CGAL_Nef_polyhedron() {}
|
||||
|
||||
virtual size_t memsize() const;
|
||||
|
@ -19,14 +20,16 @@ public:
|
|||
virtual unsigned int getDimension() const { return 3; }
|
||||
// Empty means it is a geometric node which has zero area/volume
|
||||
virtual bool isEmpty() const { return !p3; }
|
||||
virtual Geometry *copy() const { return new CGAL_Nef_polyhedron(*this); }
|
||||
|
||||
void reset() { p3.reset(); }
|
||||
CGAL_Nef_polyhedron &operator+=(const CGAL_Nef_polyhedron &other);
|
||||
CGAL_Nef_polyhedron &operator*=(const CGAL_Nef_polyhedron &other);
|
||||
CGAL_Nef_polyhedron &operator-=(const CGAL_Nef_polyhedron &other);
|
||||
CGAL_Nef_polyhedron &minkowski(const CGAL_Nef_polyhedron &other);
|
||||
CGAL_Nef_polyhedron *copy() const;
|
||||
class PolySet *convertToPolyset() const;
|
||||
void transform( const Transform3d &matrix );
|
||||
void resize(Vector3d newsize, const Eigen::Matrix<bool,3,1> &autosize);
|
||||
|
||||
shared_ptr<CGAL_Nef_polyhedron3> p3;
|
||||
};
|
||||
|
|
|
@ -21,6 +21,7 @@ public:
|
|||
virtual std::string dump() const = 0;
|
||||
virtual unsigned int getDimension() const = 0;
|
||||
virtual bool isEmpty() const = 0;
|
||||
virtual Geometry *copy() const = 0;
|
||||
|
||||
unsigned int getConvexity() const { return convexity; }
|
||||
void setConvexity(int c) { this->convexity = c; }
|
||||
|
|
|
@ -161,53 +161,6 @@ Geometry *GeometryEvaluator::applyHull3D(const AbstractNode &node)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void GeometryEvaluator::applyResize3D(CGAL_Nef_polyhedron &N,
|
||||
const Vector3d &newsize,
|
||||
const Eigen::Matrix<bool,3,1> &autosize)
|
||||
{
|
||||
// Based on resize() in Giles Bathgate's RapCAD (but not exactly)
|
||||
if (N.isEmpty()) return;
|
||||
|
||||
CGAL_Iso_cuboid_3 bb = CGALUtils::boundingBox(*N.p3);
|
||||
|
||||
std::vector<NT3> scale, bbox_size;
|
||||
for (unsigned int i=0;i<3;i++) {
|
||||
scale.push_back(NT3(1));
|
||||
bbox_size.push_back(bb.max_coord(i) - bb.min_coord(i));
|
||||
}
|
||||
int newsizemax_index = 0;
|
||||
for (unsigned int i=0;i<N.getDimension();i++) {
|
||||
if (newsize[i]) {
|
||||
if (bbox_size[i] == NT3(0)) {
|
||||
PRINT("WARNING: Resize in direction normal to flat object is not implemented");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
scale[i] = NT3(newsize[i]) / bbox_size[i];
|
||||
}
|
||||
if (newsize[i] > newsize[newsizemax_index]) newsizemax_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
NT3 autoscale = NT3(1);
|
||||
if (newsize[newsizemax_index] != 0) {
|
||||
autoscale = NT3(newsize[newsizemax_index]) / bbox_size[newsizemax_index];
|
||||
}
|
||||
for (unsigned int i=0;i<N.getDimension();i++) {
|
||||
if (autosize[i] && newsize[i]==0) scale[i] = autoscale;
|
||||
}
|
||||
|
||||
Eigen::Matrix4d t;
|
||||
t << CGAL::to_double(scale[0]), 0, 0, 0,
|
||||
0, CGAL::to_double(scale[1]), 0, 0,
|
||||
0, 0, CGAL::to_double(scale[2]), 0,
|
||||
0, 0, 0, 1;
|
||||
|
||||
N.transform(Transform3d(t));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Polygon2d *GeometryEvaluator::applyMinkowski2D(const AbstractNode &node)
|
||||
{
|
||||
std::vector<const Polygon2d *> children = collectChildren2D(node);
|
||||
|
@ -457,7 +410,7 @@ Response GeometryEvaluator::visit(State &state, const RenderNode &node)
|
|||
else if (shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(geom)) {
|
||||
// If we got a const object, make a copy
|
||||
shared_ptr<CGAL_Nef_polyhedron> newN;
|
||||
if (res.isConst()) newN.reset(N->copy());
|
||||
if (res.isConst()) newN.reset((CGAL_Nef_polyhedron*)N->copy());
|
||||
else newN = dynamic_pointer_cast<CGAL_Nef_polyhedron>(res.ptr());
|
||||
newN->setConvexity(node.convexity);
|
||||
geom = newN;
|
||||
|
@ -594,7 +547,7 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node)
|
|||
assert(N);
|
||||
// If we got a const object, make a copy
|
||||
shared_ptr<CGAL_Nef_polyhedron> newN;
|
||||
if (res.isConst()) newN.reset(N->copy());
|
||||
if (res.isConst()) newN.reset((CGAL_Nef_polyhedron*)N->copy());
|
||||
else newN = dynamic_pointer_cast<CGAL_Nef_polyhedron>(res.ptr());
|
||||
newN->transform(node.matrix);
|
||||
geom = newN;
|
||||
|
@ -1005,40 +958,31 @@ Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
|
|||
case RESIZE: {
|
||||
ResultObject res = applyToChildren(node, OPENSCAD_UNION);
|
||||
geom = res.constptr();
|
||||
|
||||
shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(res.constptr());
|
||||
if (N) {
|
||||
if (geom) {
|
||||
shared_ptr<Geometry> editablegeom;
|
||||
// If we got a const object, make a copy
|
||||
shared_ptr<CGAL_Nef_polyhedron> newN;
|
||||
if (res.isConst()) newN.reset(N->copy());
|
||||
else newN = dynamic_pointer_cast<CGAL_Nef_polyhedron>(res.ptr());
|
||||
applyResize3D(*newN, node.newsize, node.autosize);
|
||||
geom = newN;
|
||||
}
|
||||
else {
|
||||
shared_ptr<const Polygon2d> poly = dynamic_pointer_cast<const Polygon2d>(res.constptr());
|
||||
if (poly) {
|
||||
// If we got a const object, make a copy
|
||||
shared_ptr<Polygon2d> newpoly;
|
||||
if (res.isConst()) newpoly.reset(new Polygon2d(*poly));
|
||||
else newpoly = dynamic_pointer_cast<Polygon2d>(res.ptr());
|
||||
if (res.isConst()) editablegeom.reset(geom->copy());
|
||||
else editablegeom = res.ptr();
|
||||
geom = editablegeom;
|
||||
|
||||
newpoly->resize(Vector2d(node.newsize[0], node.newsize[1]),
|
||||
Eigen::Matrix<bool,2,1>(node.autosize[0], node.autosize[1]));
|
||||
shared_ptr<CGAL_Nef_polyhedron> N = dynamic_pointer_cast<CGAL_Nef_polyhedron>(editablegeom);
|
||||
if (N) {
|
||||
N->resize(node.newsize, node.autosize);
|
||||
}
|
||||
else {
|
||||
shared_ptr<const PolySet> ps = dynamic_pointer_cast<const PolySet>(res.constptr());
|
||||
if (ps) {
|
||||
// If we got a const object, make a copy
|
||||
shared_ptr<PolySet> newps;
|
||||
if (res.isConst()) newps.reset(new PolySet(*ps));
|
||||
else newps = dynamic_pointer_cast<PolySet>(res.ptr());
|
||||
|
||||
newps->resize(node.newsize, node.autosize);
|
||||
geom = newps;
|
||||
shared_ptr<Polygon2d> poly = dynamic_pointer_cast<Polygon2d>(editablegeom);
|
||||
if (poly) {
|
||||
poly->resize(Vector2d(node.newsize[0], node.newsize[1]),
|
||||
Eigen::Matrix<bool,2,1>(node.autosize[0], node.autosize[1]));
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
shared_ptr<PolySet> ps = dynamic_pointer_cast<PolySet>(editablegeom);
|
||||
if (ps) {
|
||||
ps->resize(node.newsize, node.autosize);
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ public:
|
|||
virtual std::string dump() const;
|
||||
virtual unsigned int getDimension() const { return 2; }
|
||||
virtual bool isEmpty() const;
|
||||
virtual Geometry *copy() const { return new Polygon2d(*this); }
|
||||
|
||||
void addOutline(const Outline2d &outline) { this->theoutlines.push_back(outline); }
|
||||
class PolySet *tessellate() const;
|
||||
|
|
|
@ -341,7 +341,7 @@ namespace CGALUtils {
|
|||
}
|
||||
// Initialize N with first expected geometric object
|
||||
if (!N) {
|
||||
N = chN->copy();
|
||||
N = new CGAL_Nef_polyhedron(*chN);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -420,7 +420,7 @@ namespace CGALUtils {
|
|||
try {
|
||||
switch (op) {
|
||||
case OPENSCAD_UNION:
|
||||
if (target.isEmpty()) target = *src.copy();
|
||||
if (target.isEmpty()) target = *new CGAL_Nef_polyhedron(src);
|
||||
else target += src;
|
||||
break;
|
||||
case OPENSCAD_INTERSECTION:
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
virtual std::string dump() const;
|
||||
virtual unsigned int getDimension() const { return this->dim; }
|
||||
virtual bool isEmpty() const { return polygons.size() == 0; }
|
||||
virtual Geometry *copy() const { return new PolySet(*this); }
|
||||
|
||||
size_t numPolygons() const { return polygons.size(); }
|
||||
void append_poly();
|
||||
|
|
Loading…
Reference in New Issue