mirror of https://github.com/vitalif/openscad
Implemented 3D transform of PolySets, removed some Grid usage, improved PolySet -> Polyhedron conversion, optimized operations with only one child
parent
2fc3a39cfc
commit
698aa54998
|
@ -92,30 +92,39 @@ shared_ptr<const Geometry> GeometryEvaluator::evaluateGeometry(const AbstractNod
|
|||
return GeometryCache::instance()->get(this->tree.getIdString(node));
|
||||
}
|
||||
|
||||
Geometry *GeometryEvaluator::applyToChildren(const AbstractNode &node, OpenSCADOperator op)
|
||||
GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren(const AbstractNode &node, OpenSCADOperator op)
|
||||
{
|
||||
unsigned int dim = 0;
|
||||
BOOST_FOREACH(const Geometry::ChildItem &item, this->visitedchildren[node.index()]) {
|
||||
if (item.second) {
|
||||
if (!dim) dim = item.second->getDimension();
|
||||
else if (dim != item.second->getDimension()) {
|
||||
return NULL;
|
||||
return ResultObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dim == 2) return applyToChildren2D(node, op);
|
||||
if (dim == 2) return ResultObject(applyToChildren2D(node, op));
|
||||
else if (dim == 3) return applyToChildren3D(node, op);
|
||||
return NULL;
|
||||
return ResultObject();
|
||||
}
|
||||
|
||||
Geometry *GeometryEvaluator::applyToChildren3D(const AbstractNode &node, OpenSCADOperator op)
|
||||
/*!
|
||||
Applies the operator to all child nodes of the given node.
|
||||
|
||||
May return NULL or any 3D Geometry object (can be either PolySet or CGAL_Nef_polyhedron)
|
||||
*/
|
||||
GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren3D(const AbstractNode &node, OpenSCADOperator op)
|
||||
{
|
||||
if (op == OPENSCAD_HULL) {
|
||||
return applyHull3D(node);
|
||||
return ResultObject(applyHull3D(node));
|
||||
}
|
||||
|
||||
Geometry::ChildList children = collectChildren3D(node);
|
||||
|
||||
if (children.size() == 0) return ResultObject();
|
||||
// Only one child -> this is a noop
|
||||
if (children.size() == 1) return ResultObject(children.front().second);
|
||||
|
||||
CGAL_Nef_polyhedron *N = new CGAL_Nef_polyhedron;
|
||||
BOOST_FOREACH(const Geometry::ChildItem &item, children) {
|
||||
const shared_ptr<const Geometry> &chgeom = item.second;
|
||||
|
@ -167,7 +176,7 @@ Geometry *GeometryEvaluator::applyToChildren3D(const AbstractNode &node, OpenSCA
|
|||
chnode->progress_report();
|
||||
}
|
||||
*/
|
||||
return N;
|
||||
return ResultObject(N);
|
||||
}
|
||||
|
||||
|
||||
|
@ -432,8 +441,7 @@ Response GeometryEvaluator::visit(State &state, const AbstractNode &node)
|
|||
if (state.isPostfix()) {
|
||||
shared_ptr<const class Geometry> geom;
|
||||
if (!isCached(node)) {
|
||||
const Geometry *geometry = applyToChildren(node, OPENSCAD_UNION);
|
||||
geom.reset(geometry);
|
||||
geom = applyToChildren(node, OPENSCAD_UNION).constptr();
|
||||
}
|
||||
else {
|
||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
||||
|
@ -508,10 +516,9 @@ Response GeometryEvaluator::visit(State &state, const CsgNode &node)
|
|||
{
|
||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
||||
if (state.isPostfix()) {
|
||||
shared_ptr<const class Geometry> geom;
|
||||
shared_ptr<const Geometry> geom;
|
||||
if (!isCached(node)) {
|
||||
const Geometry *geometry = applyToChildren(node, node.type);
|
||||
geom.reset(geometry);
|
||||
geom = applyToChildren(node, node.type).constptr();
|
||||
}
|
||||
else {
|
||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
||||
|
@ -540,24 +547,44 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node)
|
|||
}
|
||||
else {
|
||||
// First union all children
|
||||
Geometry *geometry = applyToChildren(node, OPENSCAD_UNION);
|
||||
if (geometry) {
|
||||
if (geometry->getDimension() == 2) {
|
||||
Polygon2d *polygons = dynamic_cast<Polygon2d*>(geometry);
|
||||
assert(polygons);
|
||||
Transform2d mat2;
|
||||
mat2.matrix() <<
|
||||
node.matrix(0,0), node.matrix(0,1), node.matrix(0,3),
|
||||
node.matrix(1,0), node.matrix(1,1), node.matrix(1,3),
|
||||
node.matrix(3,0), node.matrix(3,1), node.matrix(3,3);
|
||||
polygons->transform(mat2);
|
||||
geom.reset(polygons);
|
||||
ResultObject res = applyToChildren(node, OPENSCAD_UNION);
|
||||
geom = res.constptr();
|
||||
if (geom->getDimension() == 2) {
|
||||
shared_ptr<const Polygon2d> polygons = dynamic_pointer_cast<const Polygon2d>(geom);
|
||||
assert(polygons);
|
||||
|
||||
// If we got a const object, make a copy
|
||||
shared_ptr<Polygon2d> newpoly;
|
||||
if (res.isConst()) newpoly.reset(new Polygon2d(*polygons));
|
||||
else newpoly = dynamic_pointer_cast<Polygon2d>(res.ptr());
|
||||
|
||||
Transform2d mat2;
|
||||
mat2.matrix() <<
|
||||
node.matrix(0,0), node.matrix(0,1), node.matrix(0,3),
|
||||
node.matrix(1,0), node.matrix(1,1), node.matrix(1,3),
|
||||
node.matrix(3,0), node.matrix(3,1), node.matrix(3,3);
|
||||
newpoly->transform(mat2);
|
||||
geom = newpoly;
|
||||
}
|
||||
else if (geom->getDimension() == 3) {
|
||||
shared_ptr<const PolySet> ps = dynamic_pointer_cast<const PolySet>(geom);
|
||||
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->transform(node.matrix);
|
||||
geom = newps;
|
||||
}
|
||||
else if (geometry->getDimension() == 3) {
|
||||
CGAL_Nef_polyhedron *N = dynamic_cast<CGAL_Nef_polyhedron*>(geometry);
|
||||
else {
|
||||
shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(geom);
|
||||
assert(N);
|
||||
N->transform(node.matrix);
|
||||
geom.reset(N);
|
||||
// If we got a const object, make a copy
|
||||
shared_ptr<CGAL_Nef_polyhedron> newN;
|
||||
if (res.isConst()) newN.reset(new CGAL_Nef_polyhedron(*N));
|
||||
else newN = dynamic_pointer_cast<CGAL_Nef_polyhedron>(res.ptr());
|
||||
newN->transform(node.matrix);
|
||||
geom = newN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -739,17 +766,19 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p
|
|||
ps->setConvexity(node.convexity);
|
||||
|
||||
BOOST_FOREACH(const Outline2d &o, poly.outlines()) {
|
||||
double min_x = 0;
|
||||
double max_x = 0;
|
||||
BOOST_FOREACH(const Vector2d &v, o) {
|
||||
if (v[0] < 0) {
|
||||
PRINT("ERROR: all points for rotate_extrude() must have non-negative X coordinates");
|
||||
PRINTB("[Point (%f, %f)]", v[0] % v[1]);
|
||||
min_x = fmin(min_x, v[0]);
|
||||
max_x = fmax(max_x, v[0]);
|
||||
|
||||
if ((max_x - min_x) > max_x && (max_x - min_x) > fabs(min_x)) {
|
||||
PRINTB("ERROR: all points for rotate_extrude() must have the same X coordinate sign (range is %.2f -> %.2f)", min_x % max_x);
|
||||
delete ps;
|
||||
return NULL;
|
||||
}
|
||||
max_x = fmax(max_x, v[0]);
|
||||
}
|
||||
int fragments = get_fragments_from_r(max_x, node.fn, node.fs, node.fa);
|
||||
int fragments = get_fragments_from_r(max_x - min_x, node.fn, node.fs, node.fa);
|
||||
|
||||
std::vector<Vector3d> rings[2];
|
||||
rings[0].reserve(o.size());
|
||||
|
@ -799,7 +828,6 @@ Response GeometryEvaluator::visit(State &state, const RotateExtrudeNode &node)
|
|||
if (geometry) {
|
||||
const Polygon2d *polygons = dynamic_cast<const Polygon2d*>(geometry);
|
||||
Geometry *rotated = rotatePolygon(node, *polygons);
|
||||
assert(rotated);
|
||||
geom.reset(rotated);
|
||||
delete geometry;
|
||||
}
|
||||
|
@ -898,12 +926,11 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
|
|||
if (sumresult.size() > 0) geom.reset(ClipperUtils::toPolygon2d(sumresult));
|
||||
}
|
||||
else {
|
||||
const Geometry *geometry = applyToChildren3D(node, OPENSCAD_UNION);
|
||||
if (geometry) {
|
||||
const CGAL_Nef_polyhedron *Nptr = dynamic_cast<const CGAL_Nef_polyhedron*>(geometry);
|
||||
shared_ptr<const Geometry> newgeom = applyToChildren3D(node, OPENSCAD_UNION).constptr();
|
||||
if (newgeom) {
|
||||
shared_ptr<const CGAL_Nef_polyhedron> Nptr = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(newgeom);
|
||||
if (!Nptr) {
|
||||
// FIXME: delete this object
|
||||
Nptr = createNefPolyhedronFromGeometry(*geometry);
|
||||
Nptr.reset(createNefPolyhedronFromGeometry(*newgeom));
|
||||
}
|
||||
if (!Nptr->isNull()) {
|
||||
CGAL_Nef_polyhedron nef_poly = CGALUtils::project(*Nptr, node.cut_mode);
|
||||
|
@ -911,7 +938,6 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
|
|||
assert(poly);
|
||||
poly->setConvexity(node.convexity);
|
||||
geom.reset(poly);
|
||||
delete geometry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -938,13 +964,11 @@ Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
|
|||
if (!isCached(node)) {
|
||||
switch (node.type) {
|
||||
case MINKOWSKI: {
|
||||
const Geometry *geometry = applyToChildren(node, OPENSCAD_MINKOWSKI);
|
||||
geom.reset(geometry);
|
||||
geom = applyToChildren(node, OPENSCAD_MINKOWSKI).constptr();
|
||||
break;
|
||||
}
|
||||
case HULL: {
|
||||
const Geometry *geometry = applyToChildren(node, OPENSCAD_HULL);
|
||||
geom.reset(geometry);
|
||||
geom = applyToChildren(node, OPENSCAD_HULL).constptr();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -991,8 +1015,8 @@ Response GeometryEvaluator::visit(State &state, const RenderNode &node)
|
|||
if (state.isPostfix()) {
|
||||
shared_ptr<const Geometry> geom;
|
||||
if (!isCached(node)) {
|
||||
const Geometry *geometry = applyToChildren(node, OPENSCAD_UNION);
|
||||
const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron*>(geometry);
|
||||
geom = applyToChildren(node, OPENSCAD_UNION).constptr();
|
||||
shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(geom);
|
||||
if (N) {
|
||||
PolySet *ps = NULL;
|
||||
if (!N->isNull()) {
|
||||
|
@ -1006,9 +1030,6 @@ Response GeometryEvaluator::visit(State &state, const RenderNode &node)
|
|||
}
|
||||
geom.reset(ps);
|
||||
}
|
||||
else {
|
||||
geom.reset(geometry);
|
||||
}
|
||||
}
|
||||
else {
|
||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
||||
|
|
|
@ -34,6 +34,24 @@ public:
|
|||
const Tree &getTree() const { return this->tree; }
|
||||
|
||||
private:
|
||||
class ResultObject {
|
||||
public:
|
||||
ResultObject() : is_const(true) {}
|
||||
ResultObject(const Geometry *g) : is_const(true), const_pointer(g) {}
|
||||
ResultObject(shared_ptr<const Geometry> &g) : is_const(true), const_pointer(g) {}
|
||||
ResultObject(Geometry *g) : is_const(false), pointer(g) {}
|
||||
ResultObject(shared_ptr<Geometry> &g) : is_const(false), pointer(g) {}
|
||||
bool isConst() const { return is_const; }
|
||||
shared_ptr<Geometry> ptr() { assert(!is_const); return pointer; }
|
||||
shared_ptr<const Geometry> constptr() const {
|
||||
return is_const ? const_pointer : static_pointer_cast<const Geometry>(pointer);
|
||||
}
|
||||
private:
|
||||
bool is_const;
|
||||
shared_ptr<Geometry> pointer;
|
||||
shared_ptr<const Geometry> const_pointer;
|
||||
};
|
||||
|
||||
bool isCached(const AbstractNode &node) const;
|
||||
void smartCache(const AbstractNode &node, const shared_ptr<const Geometry> &geom);
|
||||
std::vector<const class Polygon2d *> collectChildren2D(const AbstractNode &node);
|
||||
|
@ -42,8 +60,8 @@ private:
|
|||
Polygon2d *applyHull2D(const AbstractNode &node);
|
||||
Geometry *applyHull3D(const AbstractNode &node);
|
||||
Polygon2d *applyToChildren2D(const AbstractNode &node, OpenSCADOperator op);
|
||||
Geometry *applyToChildren3D(const AbstractNode &node, OpenSCADOperator op);
|
||||
Geometry *applyToChildren(const AbstractNode &node, OpenSCADOperator op);
|
||||
ResultObject applyToChildren3D(const AbstractNode &node, OpenSCADOperator op);
|
||||
ResultObject applyToChildren(const AbstractNode &node, OpenSCADOperator op);
|
||||
void addToParent(const State &state, const AbstractNode &node, const shared_ptr<const Geometry> &geom);
|
||||
|
||||
std::map<int, Geometry::ChildList> visitedchildren;
|
||||
|
|
112
src/cgalutils.cc
112
src/cgalutils.cc
|
@ -5,6 +5,7 @@
|
|||
#include "printutils.h"
|
||||
#include "Polygon2d.h"
|
||||
#include "polyset-utils.h"
|
||||
#include "grid.h"
|
||||
|
||||
#include "cgal.h"
|
||||
#include <CGAL/convex_hull_3.h>
|
||||
|
@ -101,7 +102,7 @@ namespace CGALUtils {
|
|||
catch (const CGAL::Failure_exception &e) {
|
||||
// union && difference assert triggered by testdata/scad/bugs/rotate-diff-nonmanifold-crash.scad and testdata/scad/bugs/issue204.scad
|
||||
std::string opstr = op == OPENSCAD_UNION ? "union" : op == OPENSCAD_INTERSECTION ? "intersection" : op == OPENSCAD_DIFFERENCE ? "difference" : op == OPENSCAD_MINKOWSKI ? "minkowski" : "UNKNOWN";
|
||||
PRINTB("CGAL error in CGAL_Nef_polyhedron's %s operator: %s", opstr % e.what());
|
||||
PRINTB("CGAL error in CGALUtils::applyBinaryOperator %s: %s", opstr % e.what());
|
||||
|
||||
// Errors can result in corrupt polyhedrons, so put back the old one
|
||||
target = src;
|
||||
|
@ -123,7 +124,7 @@ namespace CGALUtils {
|
|||
newN.p3.reset(new CGAL_Nef_polyhedron3(N.p3->intersection(xy_plane, CGAL_Nef_polyhedron3::PLANE_ONLY)));
|
||||
}
|
||||
catch (const CGAL::Failure_exception &e) {
|
||||
PRINTB("CGAL error in projection node during plane intersection: %s", e.what());
|
||||
PRINTB("CGALUtils::project during plane intersection: %s", e.what());
|
||||
try {
|
||||
PRINT("Trying alternative intersection using very large thin box: ");
|
||||
std::vector<CGAL_Point_3> pts;
|
||||
|
@ -140,7 +141,7 @@ namespace CGALUtils {
|
|||
newN.p3.reset(new CGAL_Nef_polyhedron3(nef_bigbox.intersection(*N.p3)));
|
||||
}
|
||||
catch (const CGAL::Failure_exception &e) {
|
||||
PRINTB("CGAL error in projection node during bigbox intersection: %s", e.what());
|
||||
PRINTB("CGAL error in CGALUtils::project during bigbox intersection: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,7 +169,7 @@ namespace CGALUtils {
|
|||
}
|
||||
nef_poly.p2 = zremover.output_nefpoly2d;
|
||||
} catch (const CGAL::Failure_exception &e) {
|
||||
PRINTB("CGAL error in projection node while flattening: %s", e.what());
|
||||
PRINTB("CGAL error in CGALUtils::project while flattening: %s", e.what());
|
||||
}
|
||||
log << "</svg>\n";
|
||||
|
||||
|
@ -243,73 +244,52 @@ public:
|
|||
void operator()(CGAL_HDS& hds)
|
||||
{
|
||||
CGAL_Polybuilder B(hds, true);
|
||||
typedef boost::tuple<double, double, double> BuilderVertex;
|
||||
typedef std::map<BuilderVertex, size_t> BuilderMap;
|
||||
BuilderMap vertices;
|
||||
std::vector<size_t> indices(3);
|
||||
|
||||
std::vector<CGALPoint> vertices;
|
||||
Grid3d<int> vertices_idx(GRID_FINE);
|
||||
|
||||
for (size_t i = 0; i < ps.polygons.size(); i++) {
|
||||
const PolySet::Polygon *poly = &ps.polygons[i];
|
||||
for (size_t j = 0; j < poly->size(); j++) {
|
||||
const Vector3d &p = poly->at(j);
|
||||
if (!vertices_idx.has(p[0], p[1], p[2])) {
|
||||
vertices_idx.data(p[0], p[1], p[2]) = vertices.size();
|
||||
vertices.push_back(CGALPoint(p[0], p[1], p[2]));
|
||||
// Estimating same # of vertices as polygons (very rough)
|
||||
B.begin_surface(ps.polygons.size(), ps.polygons.size());
|
||||
int pidx = 0;
|
||||
printf("polyhedron(triangles=[");
|
||||
BOOST_FOREACH(const PolySet::Polygon &p, ps.polygons) {
|
||||
if (pidx++ > 0) printf(",");
|
||||
indices.clear();
|
||||
BOOST_FOREACH(const Vector3d &v, p) {
|
||||
size_t idx;
|
||||
BuilderVertex bv = boost::make_tuple(v[0], v[1], v[2]);
|
||||
if (vertices.count(bv) > 0) indices.push_back(vertices[bv]);
|
||||
else {
|
||||
indices.push_back(vertices.size());
|
||||
vertices[bv] = vertices.size();
|
||||
B.add_vertex(CGALPoint(v[0], v[1], v[2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
B.begin_surface(vertices.size(), ps.polygons.size());
|
||||
#ifdef GEN_SURFACE_DEBUG
|
||||
printf("=== CGAL Surface ===\n");
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < vertices.size(); i++) {
|
||||
const CGALPoint &p = vertices[i];
|
||||
B.add_vertex(p);
|
||||
#ifdef GEN_SURFACE_DEBUG
|
||||
printf("%d: %f %f %f\n", i, p.x().to_double(), p.y().to_double(), p.z().to_double());
|
||||
#endif
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ps.polygons.size(); i++) {
|
||||
const PolySet::Polygon *poly = &ps.polygons[i];
|
||||
std::map<int,int> fc;
|
||||
bool facet_is_degenerated = false;
|
||||
for (size_t j = 0; j < poly->size(); j++) {
|
||||
const Vector3d &p = poly->at(j);
|
||||
int v = vertices_idx.data(p[0], p[1], p[2]);
|
||||
if (fc[v]++ > 0)
|
||||
facet_is_degenerated = true;
|
||||
B.begin_facet();
|
||||
printf("[");
|
||||
int fidx = 0;
|
||||
BOOST_FOREACH(size_t i, indices) {
|
||||
B.add_vertex_to_facet(i);
|
||||
if (fidx++ > 0) printf(",");
|
||||
printf("%ld", i);
|
||||
}
|
||||
|
||||
if (!facet_is_degenerated)
|
||||
B.begin_facet();
|
||||
#ifdef GEN_SURFACE_DEBUG
|
||||
printf("F:");
|
||||
#endif
|
||||
for (size_t j = 0; j < poly->size(); j++) {
|
||||
const Vector3d &p = poly->at(j);
|
||||
#ifdef GEN_SURFACE_DEBUG
|
||||
printf(" %d (%f,%f,%f)", vertices_idx.data(p[0], p[1], p[2]), p[0], p[1], p[2]);
|
||||
#endif
|
||||
if (!facet_is_degenerated)
|
||||
B.add_vertex_to_facet(vertices_idx.data(p[0], p[1], p[2]));
|
||||
}
|
||||
#ifdef GEN_SURFACE_DEBUG
|
||||
if (facet_is_degenerated)
|
||||
printf(" (degenerated)");
|
||||
printf("\n");
|
||||
#endif
|
||||
if (!facet_is_degenerated)
|
||||
B.end_facet();
|
||||
printf("]");
|
||||
B.end_facet();
|
||||
}
|
||||
|
||||
#ifdef GEN_SURFACE_DEBUG
|
||||
printf("====================\n");
|
||||
#endif
|
||||
B.end_surface();
|
||||
printf("],\n");
|
||||
|
||||
#undef PointKey
|
||||
printf("points=[");
|
||||
int vidx = 0;
|
||||
for (int vidx=0;vidx<vertices.size();vidx++) {
|
||||
if (vidx > 0) printf(",");
|
||||
const BuilderMap::const_iterator it =
|
||||
std::find_if(vertices.begin(), vertices.end(),
|
||||
boost::bind(&BuilderMap::value_type::second, _1) == vidx);
|
||||
printf("[%g,%g,%g]", it->first.get<0>(), it->first.get<1>(), it->first.get<2>());
|
||||
}
|
||||
printf("]);\n");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -322,7 +302,7 @@ bool createPolyhedronFromPolySet(const PolySet &ps, CGAL_Polyhedron &p)
|
|||
p.delegate(builder);
|
||||
}
|
||||
catch (const CGAL::Assertion_exception &e) {
|
||||
PRINTB("CGAL error in CGAL_Build_PolySet: %s", e.what());
|
||||
PRINTB("CGAL error in CGALUtils::createPolyhedronFromPolySet: %s", e.what());
|
||||
err = true;
|
||||
}
|
||||
CGAL::set_error_behaviour(old_behaviour);
|
||||
|
@ -672,7 +652,7 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps)
|
|||
}
|
||||
}
|
||||
catch (const CGAL::Assertion_exception &e) {
|
||||
PRINTB("CGAL error in CGAL_Nef_polyhedron3(): %s", e.what());
|
||||
PRINTB("CGAL error in CGALUtils::createNefPolyhedronFromPolySet(): %s", e.what());
|
||||
}
|
||||
CGAL::set_error_behaviour(old_behaviour);
|
||||
return new CGAL_Nef_polyhedron(N);
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
#include <boost/shared_ptr.hpp>
|
||||
using boost::shared_ptr;
|
||||
using boost::dynamic_pointer_cast;
|
||||
using boost::static_pointer_cast;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
|
||||
*/
|
||||
|
||||
PolySet::PolySet() : grid(GRID_FINE), is2d(false)
|
||||
PolySet::PolySet() : is2d(false)
|
||||
{
|
||||
}
|
||||
|
||||
PolySet::PolySet(const Polygon2d &origin) : grid(GRID_FINE), is2d(true), polygon(origin)
|
||||
PolySet::PolySet(const Polygon2d &origin) : is2d(true), polygon(origin)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,6 @@ void PolySet::append_vertex(double x, double y, double z)
|
|||
|
||||
void PolySet::append_vertex(Vector3d v)
|
||||
{
|
||||
grid.align(v[0], v[1], v[2]);
|
||||
polygons.back().push_back(v);
|
||||
}
|
||||
|
||||
|
@ -101,7 +100,6 @@ void PolySet::insert_vertex(double x, double y, double z)
|
|||
|
||||
void PolySet::insert_vertex(Vector3d v)
|
||||
{
|
||||
grid.align(v[0], v[1], v[2]);
|
||||
polygons.back().insert(polygons.back().begin(), v);
|
||||
}
|
||||
|
||||
|
@ -329,7 +327,6 @@ size_t PolySet::memsize() const
|
|||
size_t mem = 0;
|
||||
BOOST_FOREACH(const Polygon &p, this->polygons) mem += p.size() * sizeof(Vector3d);
|
||||
mem += this->polygon.memsize() - sizeof(this->polygon);
|
||||
mem += this->grid.db.size() * (3 * sizeof(int64_t) + sizeof(void*)) + sizeof(Grid3d<void*>);
|
||||
mem += sizeof(PolySet);
|
||||
return mem;
|
||||
}
|
||||
|
@ -339,3 +336,11 @@ void PolySet::append(const PolySet &ps)
|
|||
this->polygons.insert(this->polygons.end(), ps.polygons.begin(), ps.polygons.end());
|
||||
}
|
||||
|
||||
void PolySet::transform(const Transform3d &mat)
|
||||
{
|
||||
BOOST_FOREACH(Polygon &p, this->polygons) {
|
||||
BOOST_FOREACH(Vector3d &v, p) {
|
||||
v = mat * v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "Geometry.h"
|
||||
#include "system-gl.h"
|
||||
#include "grid.h"
|
||||
#include "linalg.h"
|
||||
#include "renderer.h"
|
||||
#include "Polygon2d.h"
|
||||
|
@ -15,7 +14,6 @@ class PolySet : public Geometry
|
|||
public:
|
||||
typedef std::vector<Vector3d> Polygon;
|
||||
std::vector<Polygon> polygons;
|
||||
Grid3d<void*> grid;
|
||||
|
||||
bool is2d;
|
||||
|
||||
|
@ -39,6 +37,8 @@ public:
|
|||
void render_surface(Renderer::csgmode_e csgmode, const Transform3d &m, GLint *shaderinfo = NULL) const;
|
||||
void render_edges(Renderer::csgmode_e csgmode) const;
|
||||
|
||||
void transform(const Transform3d &mat);
|
||||
|
||||
private:
|
||||
Polygon2d polygon;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue