mirror of https://github.com/vitalif/openscad
Added Geometry::isEmpty, some cleanups of CGAL_Nef_polyhedron, fixed some 2D-3D-mix issues
parent
211e3bc66d
commit
b5928655e3
|
@ -388,7 +388,6 @@ SOURCES += src/cgalutils.cc \
|
|||
src/CGALRenderer.cc \
|
||||
src/CGAL_Nef_polyhedron.cc \
|
||||
src/CGAL_Nef_polyhedron_DxfData.cc \
|
||||
src/cgaladv_minkowski2.cc \
|
||||
src/cgalworker.cc \
|
||||
src/Polygon2d-CGAL.cc
|
||||
}
|
||||
|
|
|
@ -34,8 +34,6 @@ CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator-=(const CGAL_Nef_polyhedron &
|
|||
return *this;
|
||||
}
|
||||
|
||||
extern CGAL_Nef_polyhedron2 minkowski2(const CGAL_Nef_polyhedron2 &a, const CGAL_Nef_polyhedron2 &b);
|
||||
|
||||
CGAL_Nef_polyhedron &CGAL_Nef_polyhedron::minkowski(const CGAL_Nef_polyhedron &other)
|
||||
{
|
||||
if (this->dim == 3) (*this->p3) = CGAL::minkowski_sum_3(*this->p3, *other.p3);
|
||||
|
@ -44,7 +42,7 @@ CGAL_Nef_polyhedron &CGAL_Nef_polyhedron::minkowski(const CGAL_Nef_polyhedron &o
|
|||
|
||||
size_t CGAL_Nef_polyhedron::memsize() const
|
||||
{
|
||||
if (this->isNull()) return 0;
|
||||
if (this->isEmpty()) return 0;
|
||||
|
||||
size_t memsize = sizeof(CGAL_Nef_polyhedron);
|
||||
if (this->dim == 3) memsize += this->p3->bytes();
|
||||
|
@ -58,11 +56,11 @@ size_t CGAL_Nef_polyhedron::memsize() const
|
|||
*/
|
||||
PolySet *CGAL_Nef_polyhedron::convertToPolyset() const
|
||||
{
|
||||
if (this->isNull()) return new PolySet();
|
||||
if (this->isEmpty()) return new PolySet(this->dim);
|
||||
PolySet *ps = NULL;
|
||||
if (this->dim == 3) {
|
||||
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
|
||||
ps = new PolySet();
|
||||
ps = new PolySet(3);
|
||||
ps->setConvexity(this->convexity);
|
||||
bool err = true;
|
||||
std::string errmsg("");
|
||||
|
@ -92,9 +90,9 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() const
|
|||
/*!
|
||||
Deep copy
|
||||
*/
|
||||
CGAL_Nef_polyhedron CGAL_Nef_polyhedron::copy() const
|
||||
CGAL_Nef_polyhedron *CGAL_Nef_polyhedron::copy() const
|
||||
{
|
||||
CGAL_Nef_polyhedron copy = *this;
|
||||
if (copy.p3) copy.p3.reset(new CGAL_Nef_polyhedron3(*copy.p3));
|
||||
CGAL_Nef_polyhedron *copy = new CGAL_Nef_polyhedron(*this);
|
||||
if (copy->p3) copy->p3.reset(new CGAL_Nef_polyhedron3(*copy->p3));
|
||||
return copy;
|
||||
}
|
||||
|
|
|
@ -19,17 +19,15 @@ public:
|
|||
virtual BoundingBox getBoundingBox() const { assert(false && "not implemented"); }
|
||||
virtual std::string dump() const;
|
||||
virtual unsigned int getDimension() const { return this->dim; }
|
||||
|
||||
// Empty means it is a geometric node which has zero area/volume
|
||||
bool isEmpty() const { return (dim > 0 && !p3); }
|
||||
// Null means the node doesn't contain any geometry (for whatever reason)
|
||||
bool isNull() const { return !p3; }
|
||||
virtual bool isEmpty() const { return !p3; }
|
||||
|
||||
void reset() { dim=0; 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;
|
||||
CGAL_Nef_polyhedron *copy() const;
|
||||
class PolySet *convertToPolyset() const;
|
||||
void transform( const Transform3d &matrix );
|
||||
shared_ptr<CGAL_Nef_polyhedron3> p3;
|
||||
|
|
|
@ -47,7 +47,7 @@ std::string CGAL_Nef_polyhedron::dump() const
|
|||
|
||||
void CGAL_Nef_polyhedron::transform( const Transform3d &matrix )
|
||||
{
|
||||
if (!this->isNull()) {
|
||||
if (!this->isEmpty()) {
|
||||
if (this->dim == 3) {
|
||||
if (matrix.matrix().determinant() == 0) {
|
||||
PRINT("Warning: Scaling a 3D object with 0 - removing object");
|
||||
|
|
|
@ -21,6 +21,8 @@ public:
|
|||
virtual BoundingBox getBoundingBox() const = 0;
|
||||
virtual std::string dump() const = 0;
|
||||
virtual unsigned int getDimension() const = 0;
|
||||
virtual bool isEmpty() const = 0;
|
||||
|
||||
unsigned int getConvexity() const { return convexity; }
|
||||
void setConvexity(int c) { this->convexity = c; }
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren3D(const Abstr
|
|||
// Only one child -> this is a noop
|
||||
if (children.size() == 1) return ResultObject(children.front().second);
|
||||
|
||||
CGAL_Nef_polyhedron *N = new CGAL_Nef_polyhedron;
|
||||
CGAL_Nef_polyhedron *N = NULL;
|
||||
BOOST_FOREACH(const Geometry::ChildItem &item, children) {
|
||||
const shared_ptr<const Geometry> &chgeom = item.second;
|
||||
shared_ptr<const CGAL_Nef_polyhedron> chN;
|
||||
|
@ -112,9 +112,9 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren3D(const Abstr
|
|||
}
|
||||
}
|
||||
|
||||
if (N) CGALUtils::applyBinaryOperator(*N, *chN, op);
|
||||
// Initialize N on first iteration with first expected geometric object
|
||||
if (N->isNull() && !N->isEmpty()) *N = chN->copy();
|
||||
else CGALUtils::applyBinaryOperator(*N, *chN, op);
|
||||
else if (chN) N = chN->copy();
|
||||
|
||||
item.first->progress_report();
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ void GeometryEvaluator::applyResize3D(CGAL_Nef_polyhedron &N,
|
|||
const Eigen::Matrix<bool,3,1> &autosize)
|
||||
{
|
||||
// Based on resize() in Giles Bathgate's RapCAD (but not exactly)
|
||||
if (N.isNull() || N.isEmpty()) return;
|
||||
if (N.isEmpty()) return;
|
||||
|
||||
CGAL_Iso_cuboid_3 bb = CGALUtils::boundingBox(*N.p3);
|
||||
|
||||
|
@ -237,6 +237,10 @@ Polygon2d *GeometryEvaluator::applyMinkowski2D(const AbstractNode &node)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a list of Polygon2d children of the given node.
|
||||
May return empty Polygon2d object, but not NULL objects
|
||||
*/
|
||||
std::vector<const class Polygon2d *> GeometryEvaluator::collectChildren2D(const AbstractNode &node)
|
||||
{
|
||||
std::vector<const Polygon2d *> children;
|
||||
|
@ -254,13 +258,15 @@ std::vector<const class Polygon2d *> GeometryEvaluator::collectChildren2D(const
|
|||
GeometryCache::instance()->insert(this->tree.getIdString(*chnode), chgeom);
|
||||
}
|
||||
|
||||
if (chgeom && chgeom->getDimension() == 2) {
|
||||
if (chgeom) {
|
||||
if (chgeom->getDimension() == 2) {
|
||||
const Polygon2d *polygons = dynamic_cast<const Polygon2d *>(chgeom.get());
|
||||
assert(polygons);
|
||||
children.push_back(polygons);
|
||||
}
|
||||
else {
|
||||
PRINT("WARNING: Ignoring 3D child object for 2D operation");
|
||||
}
|
||||
else {
|
||||
PRINT("WARNING: Ignoring 3D child object for 2D operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
return children;
|
||||
|
@ -286,6 +292,10 @@ void GeometryEvaluator::smartCache(const AbstractNode &node,
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a list of 3D Geometry children of the given node.
|
||||
May return empty geometries, but not NULL objects
|
||||
*/
|
||||
Geometry::ChildList GeometryEvaluator::collectChildren3D(const AbstractNode &node)
|
||||
{
|
||||
Geometry::ChildList children;
|
||||
|
@ -301,13 +311,13 @@ Geometry::ChildList GeometryEvaluator::collectChildren3D(const AbstractNode &nod
|
|||
// sibling object.
|
||||
smartCache(*chnode, chgeom);
|
||||
|
||||
if (chgeom && chgeom->getDimension() == 3) {
|
||||
if (chgeom) {
|
||||
if (chgeom->isEmpty() || chgeom->getDimension() == 3) {
|
||||
children.push_back(item);
|
||||
}
|
||||
else {
|
||||
PRINT("ERROR: Only 3D children are supported by this operation!");
|
||||
shared_ptr<const Geometry> nullp;
|
||||
children.push_back(Geometry::ChildItem(item.first, nullp));
|
||||
}
|
||||
else {
|
||||
PRINT("WARNING: Ignoring 2D child object for 3D operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
return children;
|
||||
|
@ -609,7 +619,7 @@ static void add_slice(PolySet *ps, const Polygon2d &poly,
|
|||
*/
|
||||
static Geometry *extrudePolygon(const LinearExtrudeNode &node, const Polygon2d &poly)
|
||||
{
|
||||
PolySet *ps = new PolySet();
|
||||
PolySet *ps = new PolySet(3);
|
||||
ps->setConvexity(node.convexity);
|
||||
if (node.height <= 0) return ps;
|
||||
|
||||
|
@ -714,7 +724,7 @@ static void fill_ring(std::vector<Vector3d> &ring, const Outline2d &o, double a)
|
|||
*/
|
||||
static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &poly)
|
||||
{
|
||||
PolySet *ps = new PolySet();
|
||||
PolySet *ps = new PolySet(3);
|
||||
ps->setConvexity(node.convexity);
|
||||
|
||||
BOOST_FOREACH(const Outline2d &o, poly.outlines()) {
|
||||
|
@ -886,7 +896,7 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
|
|||
if (!Nptr) {
|
||||
Nptr.reset(createNefPolyhedronFromGeometry(*newgeom));
|
||||
}
|
||||
if (!Nptr->isNull()) {
|
||||
if (!Nptr->isEmpty()) {
|
||||
Polygon2d *poly = CGALUtils::project(*Nptr, node.cut_mode);
|
||||
assert(poly);
|
||||
poly->setConvexity(node.convexity);
|
||||
|
|
|
@ -106,7 +106,6 @@ mark_domains(CDT &cdt)
|
|||
PolySet *Polygon2d::tessellate() const
|
||||
{
|
||||
PolySet *polyset = new PolySet(*this);
|
||||
polyset->is2d = true;
|
||||
|
||||
Polygon2DCGAL::CDT cdt; // Uses a constrained Delaunay triangulator.
|
||||
OPENSCAD_CGAL_ERROR_BEGIN;
|
||||
|
|
|
@ -47,6 +47,11 @@ std::string Polygon2d::dump() const
|
|||
return out.str();
|
||||
}
|
||||
|
||||
bool Polygon2d::isEmpty() const
|
||||
{
|
||||
return this->theoutlines.empty();
|
||||
}
|
||||
|
||||
void Polygon2d::transform(const Transform2d &mat)
|
||||
{
|
||||
BOOST_FOREACH(Outline2d &o, this->theoutlines) {
|
||||
|
|
|
@ -19,6 +19,7 @@ public:
|
|||
virtual BoundingBox getBoundingBox() const;
|
||||
virtual std::string dump() const;
|
||||
virtual unsigned int getDimension() const { return 2; }
|
||||
virtual bool isEmpty() const;
|
||||
|
||||
void addOutline(const Outline2d &outline) { this->theoutlines.push_back(outline); }
|
||||
class PolySet *tessellate() const;
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* OpenSCAD (www.openscad.org)
|
||||
* Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
|
||||
* Marius Kintel <marius@kintel.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* As a special exception, you have permission to link this program
|
||||
* with the CGAL library and distribute executables, as long as you
|
||||
* follow the requirements of the GNU GPL in regard to all of the
|
||||
* software in the executable aside from CGAL.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_CGAL
|
||||
|
||||
#include "printutils.h"
|
||||
#include "grid.h"
|
||||
#include "cgal.h"
|
||||
|
||||
extern CGAL_Poly2 nef2p2(CGAL_Nef_polyhedron2 p);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pretty-print a CGAL polygon.
|
||||
//
|
||||
template<class Kernel, class Container>
|
||||
void print_polygon (const CGAL::Polygon_2<Kernel, Container>& P)
|
||||
{
|
||||
typename CGAL::Polygon_2<Kernel, Container>::Vertex_const_iterator vit;
|
||||
|
||||
std::cout << "[ " << P.size() << " vertices:";
|
||||
for (vit = P.vertices_begin(); vit != P.vertices_end(); ++vit)
|
||||
std::cout << " (" << *vit << ')';
|
||||
std::cout << " ]" << std::endl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pretty-print a polygon with holes.
|
||||
//
|
||||
template<class Kernel, class Container>
|
||||
void print_polygon_with_holes (const CGAL::Polygon_with_holes_2<Kernel, Container>& pwh) {
|
||||
if (! pwh.is_unbounded()) {
|
||||
std::cout << "{ Outer boundary = ";
|
||||
print_polygon (pwh.outer_boundary());
|
||||
} else
|
||||
std::cout << "{ Unbounded polygon." << std::endl;
|
||||
|
||||
typename CGAL::Polygon_with_holes_2<Kernel,Container>::Hole_const_iterator hit;
|
||||
unsigned int k = 1;
|
||||
|
||||
std::cout << " " << pwh.number_of_holes() << " holes:" << std::endl;
|
||||
for (hit = pwh.holes_begin(); hit != pwh.holes_end(); ++hit, ++k) {
|
||||
std::cout << " Hole #" << k << " = ";
|
||||
print_polygon (*hit);
|
||||
}
|
||||
std::cout << " }" << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CGAL_Poly2 nef2p2(CGAL_Nef_polyhedron2 p)
|
||||
{
|
||||
std::list<CGAL_ExactKernel2::Point_2> points;
|
||||
Grid2d<int> grid(GRID_COARSE);
|
||||
|
||||
typedef CGAL_Nef_polyhedron2::Explorer Explorer;
|
||||
typedef Explorer::Face_const_iterator fci_t;
|
||||
typedef Explorer::Halfedge_around_face_const_circulator heafcc_t;
|
||||
Explorer E = p.explorer();
|
||||
|
||||
for (fci_t fit = E.faces_begin(), facesend = E.faces_end(); fit != facesend; ++fit)
|
||||
{
|
||||
if (!E.mark(fit)) {
|
||||
continue;
|
||||
}
|
||||
//if (fit != E.faces_begin()) {
|
||||
if (points.size() != 0) {
|
||||
PRINT("WARNING: minkowski() and hull() is not implemented for 2d objects with holes!");
|
||||
break;
|
||||
}
|
||||
|
||||
heafcc_t fcirc(E.halfedge(fit)), fend(fcirc);
|
||||
CGAL_For_all(fcirc, fend) {
|
||||
if (E.is_standard(E.target(fcirc))) {
|
||||
Explorer::Point ep = E.point(E.target(fcirc));
|
||||
double x = to_double(ep.x()), y = to_double(ep.y());
|
||||
grid.align(x, y);
|
||||
points.push_back(CGAL_ExactKernel2::Point_2(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CGAL_Poly2(points.begin(), points.end());
|
||||
}
|
||||
static CGAL_Nef_polyhedron2 p2nef2(CGAL_Poly2 p2) {
|
||||
std::list<CGAL_Nef_polyhedron2::Point> points;
|
||||
for (size_t j = 0; j < p2.size(); j++) {
|
||||
double x = to_double(p2[j].x());
|
||||
double y = to_double(p2[j].y());
|
||||
CGAL_Nef_polyhedron2::Point p = CGAL_Nef_polyhedron2::Point(x, y);
|
||||
points.push_back(p);
|
||||
}
|
||||
return CGAL_Nef_polyhedron2(points.begin(), points.end(), CGAL_Nef_polyhedron2::INCLUDED);
|
||||
}
|
||||
|
||||
CGAL_Nef_polyhedron2 minkowski2(const CGAL_Nef_polyhedron2 &a, const CGAL_Nef_polyhedron2 &b)
|
||||
{
|
||||
CGAL_Poly2 ap = nef2p2(a), bp = nef2p2(b);
|
||||
|
||||
if (ap.size() == 0) {
|
||||
PRINT("WARNING: minkowski() could not get any points from object 1!");
|
||||
return CGAL_Nef_polyhedron2();
|
||||
} else if (bp.size() == 0) {
|
||||
PRINT("WARNING: minkowski() could not get any points from object 2!");
|
||||
return CGAL_Nef_polyhedron2();
|
||||
} else {
|
||||
CGAL_Poly2h x = minkowski_sum_2(ap, bp);
|
||||
|
||||
// Make a CGAL_Nef_polyhedron2 out of just the boundary for starters
|
||||
return p2nef2(x.outer_boundary());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -85,7 +85,7 @@ namespace CGALUtils {
|
|||
try {
|
||||
switch (op) {
|
||||
case OPENSCAD_UNION:
|
||||
if (target.isEmpty()) target = src.copy();
|
||||
if (target.isEmpty()) target = *src.copy();
|
||||
else target += src;
|
||||
break;
|
||||
case OPENSCAD_INTERSECTION:
|
||||
|
@ -402,7 +402,7 @@ void ZRemover::visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet )
|
|||
static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps)
|
||||
{
|
||||
assert(ps.getDimension() == 3);
|
||||
if (ps.empty()) return new CGAL_Nef_polyhedron(3);
|
||||
if (ps.isEmpty()) return new CGAL_Nef_polyhedron(3);
|
||||
|
||||
CGAL_Nef_polyhedron3 *N = NULL;
|
||||
bool plane_error = false;
|
||||
|
@ -423,7 +423,7 @@ static CGAL_Nef_polyhedron *createNefPolyhedronFromPolySet(const PolySet &ps)
|
|||
}
|
||||
}
|
||||
if (plane_error) try {
|
||||
PolySet ps2;
|
||||
PolySet ps2(3);
|
||||
CGAL_Polyhedron P;
|
||||
PolysetUtils::tessellate_faces(ps, ps2);
|
||||
bool err = createPolyhedronFromPolySet(ps2,P);
|
||||
|
|
|
@ -109,8 +109,9 @@ shared_ptr<CSGTerm> CSGTerm::createCSGTerm(type_e type, CSGTerm *left, CSGTerm *
|
|||
}
|
||||
|
||||
CSGTerm::CSGTerm(const shared_ptr<const Geometry> &geom, const Transform3d &matrix, const Color4f &color, const std::string &label)
|
||||
: type(TYPE_PRIMITIVE), geom(geom), label(label), flag(CSGTerm::FLAG_NONE), m(matrix), color(color)
|
||||
: type(TYPE_PRIMITIVE), label(label), flag(CSGTerm::FLAG_NONE), m(matrix), color(color)
|
||||
{
|
||||
if (geom && !geom->isEmpty()) this->geom = geom;
|
||||
initBoundingBox();
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ void exportFile(const class Geometry *root_geom, std::ostream &output, FileForma
|
|||
|
||||
void export_stl(const PolySet *ps, std::ostream &output)
|
||||
{
|
||||
PolySet triangulated;
|
||||
PolySet triangulated(3);
|
||||
PolysetUtils::tessellate_faces(*ps, triangulated);
|
||||
|
||||
setlocale(LC_NUMERIC, "C"); // Ensure radix is . (not ,) in output
|
||||
|
|
|
@ -182,22 +182,26 @@ void read_stl_facet( std::ifstream &f, stl_facet &facet )
|
|||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
Will return an empty geometry if the import failed, but not NULL
|
||||
*/
|
||||
Geometry *ImportNode::createGeometry() const
|
||||
{
|
||||
Geometry *g = NULL;
|
||||
|
||||
if (this->type == TYPE_STL)
|
||||
{
|
||||
switch (this->type) {
|
||||
case TYPE_STL: {
|
||||
PolySet *p = new PolySet(3);
|
||||
g = p;
|
||||
|
||||
handle_dep((std::string)this->filename);
|
||||
// Open file and position at the end
|
||||
std::ifstream f(this->filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if (!f.good()) {
|
||||
PRINTB("WARNING: Can't open import file '%s'.", this->filename);
|
||||
return NULL;
|
||||
return g;
|
||||
}
|
||||
|
||||
PolySet *p = new PolySet();
|
||||
|
||||
boost::regex ex_sfe("solid|facet|endloop");
|
||||
boost::regex ex_outer("outer loop");
|
||||
boost::regex ex_vertex("vertex");
|
||||
|
@ -270,11 +274,11 @@ Geometry *ImportNode::createGeometry() const
|
|||
p->append_vertex(facet.data.x3, facet.data.y3, facet.data.z3);
|
||||
}
|
||||
}
|
||||
g = p;
|
||||
}
|
||||
|
||||
else if (this->type == TYPE_OFF)
|
||||
{
|
||||
break;
|
||||
case TYPE_OFF: {
|
||||
PolySet *p = new PolySet(3);
|
||||
g = p;
|
||||
#ifdef ENABLE_CGAL
|
||||
CGAL_Polyhedron poly;
|
||||
std::ifstream file(this->filename.c_str(), std::ios::in | std::ios::binary);
|
||||
|
@ -285,24 +289,21 @@ Geometry *ImportNode::createGeometry() const
|
|||
file >> poly;
|
||||
file.close();
|
||||
|
||||
PolySet *p = new PolySet();
|
||||
bool err = createPolySetFromPolyhedron(poly, *p);
|
||||
if (err) delete p;
|
||||
else g = p;
|
||||
}
|
||||
#else
|
||||
PRINT("WARNING: OFF import requires CGAL.");
|
||||
#endif
|
||||
}
|
||||
|
||||
else if (this->type == TYPE_DXF)
|
||||
{
|
||||
break;
|
||||
case TYPE_DXF: {
|
||||
DxfData dd(this->fn, this->fs, this->fa, this->filename, this->layername, this->origin_x, this->origin_y, this->scale);
|
||||
g = dd.toPolygon2d();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
default:
|
||||
PRINTB("ERROR: Unsupported file format while trying to import file '%s'", this->filename);
|
||||
g = new PolySet(0);
|
||||
}
|
||||
|
||||
if (g) g->setConvexity(this->convexity);
|
||||
|
|
|
@ -1315,7 +1315,7 @@ void MainWindow::actionRenderDone(shared_ptr<const Geometry> root_geom)
|
|||
PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60));
|
||||
|
||||
if (const CGAL_Nef_polyhedron *N = dynamic_cast<const CGAL_Nef_polyhedron *>(root_geom.get())) {
|
||||
if (!N->isNull()) {
|
||||
if (!N->isEmpty()) {
|
||||
if (N->getDimension() == 3) {
|
||||
PRINT(" Top level object is a 3D object:");
|
||||
PRINTB(" Simple: %6s", (N->p3->is_simple() ? "yes" : "no"));
|
||||
|
|
|
@ -44,11 +44,11 @@
|
|||
|
||||
*/
|
||||
|
||||
PolySet::PolySet() : is2d(false)
|
||||
PolySet::PolySet(unsigned int dim) : dim(dim)
|
||||
{
|
||||
}
|
||||
|
||||
PolySet::PolySet(const Polygon2d &origin) : is2d(true), polygon(origin)
|
||||
PolySet::PolySet(const Polygon2d &origin) : polygon(origin), dim(2)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ std::string PolySet::dump() const
|
|||
{
|
||||
std::stringstream out;
|
||||
out << "PolySet:"
|
||||
<< "\n dimensions:" << std::string( this->is2d ? "2" : "3" )
|
||||
<< "\n dimensions:" << this->dim
|
||||
<< "\n convexity:" << this->convexity
|
||||
<< "\n num polygons: " << polygons.size()
|
||||
<< "\n num outlines: " << polygon.outlines().size()
|
||||
|
@ -165,7 +165,7 @@ void PolySet::render_surface(Renderer::csgmode_e csgmode, const Transform3d &m,
|
|||
glUniform1f(shaderinfo[8], shaderinfo[10]);
|
||||
}
|
||||
#endif /* ENABLE_OPENCSG */
|
||||
if (this->is2d) {
|
||||
if (this->dim == 2) {
|
||||
// Render 2D objects 1mm thick, but differences slightly larger
|
||||
double zbase = 1 + (csgmode & CSGMODE_DIFFERENCE_FLAG) * 0.1;
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
@ -241,7 +241,7 @@ void PolySet::render_surface(Renderer::csgmode_e csgmode, const Transform3d &m,
|
|||
}
|
||||
}
|
||||
glEnd();
|
||||
} else {
|
||||
} else if (this->dim == 3) {
|
||||
for (size_t i = 0; i < polygons.size(); i++) {
|
||||
const Polygon *poly = &polygons[i];
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
@ -269,6 +269,9 @@ void PolySet::render_surface(Renderer::csgmode_e csgmode, const Transform3d &m,
|
|||
glEnd();
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(false && "Cannot render object with no dimension");
|
||||
}
|
||||
}
|
||||
|
||||
/*! This is used in throwntogether and CGAL mode
|
||||
|
@ -280,7 +283,7 @@ void PolySet::render_surface(Renderer::csgmode_e csgmode, const Transform3d &m,
|
|||
void PolySet::render_edges(Renderer::csgmode_e csgmode) const
|
||||
{
|
||||
glDisable(GL_LIGHTING);
|
||||
if (this->is2d) {
|
||||
if (this->dim == 2) {
|
||||
if (csgmode == Renderer::CSGMODE_NONE) {
|
||||
// Render only outlines
|
||||
BOOST_FOREACH(const Outline2d &o, polygon.outlines()) {
|
||||
|
@ -313,7 +316,7 @@ void PolySet::render_edges(Renderer::csgmode_e csgmode) const
|
|||
glEnd();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (dim == 3) {
|
||||
for (size_t i = 0; i < polygons.size(); i++) {
|
||||
const Polygon *poly = &polygons[i];
|
||||
glBegin(GL_LINE_LOOP);
|
||||
|
@ -324,6 +327,9 @@ void PolySet::render_edges(Renderer::csgmode_e csgmode) const
|
|||
glEnd();
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(false && "Cannot render object with no dimension");
|
||||
}
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,18 +15,16 @@ public:
|
|||
typedef std::vector<Vector3d> Polygon;
|
||||
std::vector<Polygon> polygons;
|
||||
|
||||
bool is2d;
|
||||
|
||||
PolySet();
|
||||
PolySet(unsigned int dim);
|
||||
PolySet(const Polygon2d &origin);
|
||||
virtual ~PolySet();
|
||||
|
||||
virtual size_t memsize() const;
|
||||
virtual BoundingBox getBoundingBox() const;
|
||||
virtual std::string dump() const;
|
||||
virtual unsigned int getDimension() const { return this->is2d ? 2 : 3; }
|
||||
virtual unsigned int getDimension() const { return this->dim; }
|
||||
virtual bool isEmpty() const { return polygons.size() == 0; }
|
||||
|
||||
bool empty() const { return polygons.size() == 0; }
|
||||
size_t numPolygons() const { return polygons.size(); }
|
||||
void append_poly();
|
||||
void append_vertex(double x, double y, double z = 0.0);
|
||||
|
@ -43,6 +41,7 @@ public:
|
|||
|
||||
private:
|
||||
Polygon2d polygon;
|
||||
unsigned int dim;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -292,202 +292,206 @@ static void generate_circle(point2d *circle, double r, int fragments)
|
|||
|
||||
/*!
|
||||
Creates geometry for this node.
|
||||
May return NULL if geometry creation failed.
|
||||
*/
|
||||
May return an empty Geometry creation failed, but will not return NULL.
|
||||
*/
|
||||
Geometry *PrimitiveNode::createGeometry() const
|
||||
{
|
||||
Geometry *g = NULL;
|
||||
|
||||
if (this->type == CUBE && this->x > 0 && this->y > 0 && this->z > 0)
|
||||
{
|
||||
PolySet *p = new PolySet();
|
||||
switch (this->type) {
|
||||
case CUBE: {
|
||||
PolySet *p = new PolySet(3);
|
||||
g = p;
|
||||
double x1, x2, y1, y2, z1, z2;
|
||||
if (this->center) {
|
||||
x1 = -this->x/2;
|
||||
x2 = +this->x/2;
|
||||
y1 = -this->y/2;
|
||||
y2 = +this->y/2;
|
||||
z1 = -this->z/2;
|
||||
z2 = +this->z/2;
|
||||
} else {
|
||||
x1 = y1 = z1 = 0;
|
||||
x2 = this->x;
|
||||
y2 = this->y;
|
||||
z2 = this->z;
|
||||
if (this->x > 0 && this->y > 0 && this->z > 0) {
|
||||
double x1, x2, y1, y2, z1, z2;
|
||||
if (this->center) {
|
||||
x1 = -this->x/2;
|
||||
x2 = +this->x/2;
|
||||
y1 = -this->y/2;
|
||||
y2 = +this->y/2;
|
||||
z1 = -this->z/2;
|
||||
z2 = +this->z/2;
|
||||
} else {
|
||||
x1 = y1 = z1 = 0;
|
||||
x2 = this->x;
|
||||
y2 = this->y;
|
||||
z2 = this->z;
|
||||
}
|
||||
|
||||
p->append_poly(); // top
|
||||
p->append_vertex(x1, y1, z2);
|
||||
p->append_vertex(x2, y1, z2);
|
||||
p->append_vertex(x2, y2, z2);
|
||||
p->append_vertex(x1, y2, z2);
|
||||
|
||||
p->append_poly(); // bottom
|
||||
p->append_vertex(x1, y2, z1);
|
||||
p->append_vertex(x2, y2, z1);
|
||||
p->append_vertex(x2, y1, z1);
|
||||
p->append_vertex(x1, y1, z1);
|
||||
|
||||
p->append_poly(); // side1
|
||||
p->append_vertex(x1, y1, z1);
|
||||
p->append_vertex(x2, y1, z1);
|
||||
p->append_vertex(x2, y1, z2);
|
||||
p->append_vertex(x1, y1, z2);
|
||||
|
||||
p->append_poly(); // side2
|
||||
p->append_vertex(x2, y1, z1);
|
||||
p->append_vertex(x2, y2, z1);
|
||||
p->append_vertex(x2, y2, z2);
|
||||
p->append_vertex(x2, y1, z2);
|
||||
|
||||
p->append_poly(); // side3
|
||||
p->append_vertex(x2, y2, z1);
|
||||
p->append_vertex(x1, y2, z1);
|
||||
p->append_vertex(x1, y2, z2);
|
||||
p->append_vertex(x2, y2, z2);
|
||||
|
||||
p->append_poly(); // side4
|
||||
p->append_vertex(x1, y2, z1);
|
||||
p->append_vertex(x1, y1, z1);
|
||||
p->append_vertex(x1, y1, z2);
|
||||
p->append_vertex(x1, y2, z2);
|
||||
}
|
||||
|
||||
p->append_poly(); // top
|
||||
p->append_vertex(x1, y1, z2);
|
||||
p->append_vertex(x2, y1, z2);
|
||||
p->append_vertex(x2, y2, z2);
|
||||
p->append_vertex(x1, y2, z2);
|
||||
|
||||
p->append_poly(); // bottom
|
||||
p->append_vertex(x1, y2, z1);
|
||||
p->append_vertex(x2, y2, z1);
|
||||
p->append_vertex(x2, y1, z1);
|
||||
p->append_vertex(x1, y1, z1);
|
||||
|
||||
p->append_poly(); // side1
|
||||
p->append_vertex(x1, y1, z1);
|
||||
p->append_vertex(x2, y1, z1);
|
||||
p->append_vertex(x2, y1, z2);
|
||||
p->append_vertex(x1, y1, z2);
|
||||
|
||||
p->append_poly(); // side2
|
||||
p->append_vertex(x2, y1, z1);
|
||||
p->append_vertex(x2, y2, z1);
|
||||
p->append_vertex(x2, y2, z2);
|
||||
p->append_vertex(x2, y1, z2);
|
||||
|
||||
p->append_poly(); // side3
|
||||
p->append_vertex(x2, y2, z1);
|
||||
p->append_vertex(x1, y2, z1);
|
||||
p->append_vertex(x1, y2, z2);
|
||||
p->append_vertex(x2, y2, z2);
|
||||
|
||||
p->append_poly(); // side4
|
||||
p->append_vertex(x1, y2, z1);
|
||||
p->append_vertex(x1, y1, z1);
|
||||
p->append_vertex(x1, y1, z2);
|
||||
p->append_vertex(x1, y2, z2);
|
||||
}
|
||||
|
||||
if (this->type == SPHERE && this->r1 > 0)
|
||||
{
|
||||
PolySet *p = new PolySet();
|
||||
break;
|
||||
case SPHERE: {
|
||||
PolySet *p = new PolySet(3);
|
||||
g = p;
|
||||
struct ring_s {
|
||||
point2d *points;
|
||||
double z;
|
||||
};
|
||||
if (this->r1 > 0) {
|
||||
struct ring_s {
|
||||
point2d *points;
|
||||
double z;
|
||||
};
|
||||
|
||||
int fragments = Calc::get_fragments_from_r(r1, fn, fs, fa);
|
||||
int rings = (fragments+1)/2;
|
||||
int fragments = Calc::get_fragments_from_r(r1, fn, fs, fa);
|
||||
int rings = (fragments+1)/2;
|
||||
// Uncomment the following three lines to enable experimental sphere tesselation
|
||||
// if (rings % 2 == 0) rings++; // To ensure that the middle ring is at phi == 0 degrees
|
||||
|
||||
ring_s *ring = new ring_s[rings];
|
||||
ring_s *ring = new ring_s[rings];
|
||||
|
||||
// double offset = 0.5 * ((fragments / 2) % 2);
|
||||
for (int i = 0; i < rings; i++) {
|
||||
for (int i = 0; i < rings; i++) {
|
||||
// double phi = (M_PI * (i + offset)) / (fragments/2);
|
||||
double phi = (M_PI * (i + 0.5)) / rings;
|
||||
double r = r1 * sin(phi);
|
||||
ring[i].z = r1 * cos(phi);
|
||||
ring[i].points = new point2d[fragments];
|
||||
generate_circle(ring[i].points, r, fragments);
|
||||
}
|
||||
double phi = (M_PI * (i + 0.5)) / rings;
|
||||
double r = r1 * sin(phi);
|
||||
ring[i].z = r1 * cos(phi);
|
||||
ring[i].points = new point2d[fragments];
|
||||
generate_circle(ring[i].points, r, fragments);
|
||||
}
|
||||
|
||||
p->append_poly();
|
||||
for (int i = 0; i < fragments; i++)
|
||||
p->append_vertex(ring[0].points[i].x, ring[0].points[i].y, ring[0].z);
|
||||
p->append_poly();
|
||||
for (int i = 0; i < fragments; i++)
|
||||
p->append_vertex(ring[0].points[i].x, ring[0].points[i].y, ring[0].z);
|
||||
|
||||
for (int i = 0; i < rings-1; i++) {
|
||||
ring_s *r1 = &ring[i];
|
||||
ring_s *r2 = &ring[i+1];
|
||||
int r1i = 0, r2i = 0;
|
||||
while (r1i < fragments || r2i < fragments)
|
||||
{
|
||||
if (r1i >= fragments)
|
||||
goto sphere_next_r2;
|
||||
if (r2i >= fragments)
|
||||
goto sphere_next_r1;
|
||||
if ((double)r1i / fragments <
|
||||
(double)r2i / fragments)
|
||||
for (int i = 0; i < rings-1; i++) {
|
||||
ring_s *r1 = &ring[i];
|
||||
ring_s *r2 = &ring[i+1];
|
||||
int r1i = 0, r2i = 0;
|
||||
while (r1i < fragments || r2i < fragments)
|
||||
{
|
||||
sphere_next_r1:
|
||||
p->append_poly();
|
||||
int r1j = (r1i+1) % fragments;
|
||||
p->insert_vertex(r1->points[r1i].x, r1->points[r1i].y, r1->z);
|
||||
p->insert_vertex(r1->points[r1j].x, r1->points[r1j].y, r1->z);
|
||||
p->insert_vertex(r2->points[r2i % fragments].x, r2->points[r2i % fragments].y, r2->z);
|
||||
r1i++;
|
||||
} else {
|
||||
sphere_next_r2:
|
||||
p->append_poly();
|
||||
int r2j = (r2i+1) % fragments;
|
||||
p->append_vertex(r2->points[r2i].x, r2->points[r2i].y, r2->z);
|
||||
p->append_vertex(r2->points[r2j].x, r2->points[r2j].y, r2->z);
|
||||
p->append_vertex(r1->points[r1i % fragments].x, r1->points[r1i % fragments].y, r1->z);
|
||||
r2i++;
|
||||
if (r1i >= fragments)
|
||||
goto sphere_next_r2;
|
||||
if (r2i >= fragments)
|
||||
goto sphere_next_r1;
|
||||
if ((double)r1i / fragments <
|
||||
(double)r2i / fragments)
|
||||
{
|
||||
sphere_next_r1:
|
||||
p->append_poly();
|
||||
int r1j = (r1i+1) % fragments;
|
||||
p->insert_vertex(r1->points[r1i].x, r1->points[r1i].y, r1->z);
|
||||
p->insert_vertex(r1->points[r1j].x, r1->points[r1j].y, r1->z);
|
||||
p->insert_vertex(r2->points[r2i % fragments].x, r2->points[r2i % fragments].y, r2->z);
|
||||
r1i++;
|
||||
} else {
|
||||
sphere_next_r2:
|
||||
p->append_poly();
|
||||
int r2j = (r2i+1) % fragments;
|
||||
p->append_vertex(r2->points[r2i].x, r2->points[r2i].y, r2->z);
|
||||
p->append_vertex(r2->points[r2j].x, r2->points[r2j].y, r2->z);
|
||||
p->append_vertex(r1->points[r1i % fragments].x, r1->points[r1i % fragments].y, r1->z);
|
||||
r2i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p->append_poly();
|
||||
for (int i = 0; i < fragments; i++)
|
||||
p->insert_vertex(ring[rings-1].points[i].x,
|
||||
ring[rings-1].points[i].y,
|
||||
ring[rings-1].z);
|
||||
|
||||
delete[] ring;
|
||||
}
|
||||
|
||||
p->append_poly();
|
||||
for (int i = 0; i < fragments; i++)
|
||||
p->insert_vertex(ring[rings-1].points[i].x, ring[rings-1].points[i].y, ring[rings-1].z);
|
||||
|
||||
delete[] ring;
|
||||
}
|
||||
|
||||
if (this->type == CYLINDER &&
|
||||
this->h > 0 && this->r1 >=0 && this->r2 >= 0 && (this->r1 > 0 || this->r2 > 0))
|
||||
{
|
||||
PolySet *p = new PolySet();
|
||||
break;
|
||||
case CYLINDER: {
|
||||
PolySet *p = new PolySet(3);
|
||||
g = p;
|
||||
int fragments = Calc::get_fragments_from_r(fmax(this->r1, this->r2), this->fn, this->fs, this->fa);
|
||||
if (this->h > 0 && this->r1 >=0 && this->r2 >= 0 && (this->r1 > 0 || this->r2 > 0)) {
|
||||
int fragments = Calc::get_fragments_from_r(fmax(this->r1, this->r2), this->fn, this->fs, this->fa);
|
||||
|
||||
double z1, z2;
|
||||
if (this->center) {
|
||||
z1 = -this->h/2;
|
||||
z2 = +this->h/2;
|
||||
} else {
|
||||
z1 = 0;
|
||||
z2 = this->h;
|
||||
}
|
||||
|
||||
point2d *circle1 = new point2d[fragments];
|
||||
point2d *circle2 = new point2d[fragments];
|
||||
|
||||
generate_circle(circle1, r1, fragments);
|
||||
generate_circle(circle2, r2, fragments);
|
||||
|
||||
for (int i=0; i<fragments; i++) {
|
||||
int j = (i+1) % fragments;
|
||||
if (r1 == r2) {
|
||||
p->append_poly();
|
||||
p->insert_vertex(circle1[i].x, circle1[i].y, z1);
|
||||
p->insert_vertex(circle2[i].x, circle2[i].y, z2);
|
||||
p->insert_vertex(circle2[j].x, circle2[j].y, z2);
|
||||
p->insert_vertex(circle1[j].x, circle1[j].y, z1);
|
||||
double z1, z2;
|
||||
if (this->center) {
|
||||
z1 = -this->h/2;
|
||||
z2 = +this->h/2;
|
||||
} else {
|
||||
if (r1 > 0) {
|
||||
z1 = 0;
|
||||
z2 = this->h;
|
||||
}
|
||||
|
||||
point2d *circle1 = new point2d[fragments];
|
||||
point2d *circle2 = new point2d[fragments];
|
||||
|
||||
generate_circle(circle1, r1, fragments);
|
||||
generate_circle(circle2, r2, fragments);
|
||||
|
||||
for (int i=0; i<fragments; i++) {
|
||||
int j = (i+1) % fragments;
|
||||
if (r1 == r2) {
|
||||
p->append_poly();
|
||||
p->insert_vertex(circle1[i].x, circle1[i].y, z1);
|
||||
p->insert_vertex(circle2[i].x, circle2[i].y, z2);
|
||||
p->insert_vertex(circle1[j].x, circle1[j].y, z1);
|
||||
}
|
||||
if (r2 > 0) {
|
||||
p->append_poly();
|
||||
p->insert_vertex(circle2[i].x, circle2[i].y, z2);
|
||||
p->insert_vertex(circle2[j].x, circle2[j].y, z2);
|
||||
p->insert_vertex(circle1[j].x, circle1[j].y, z1);
|
||||
} else {
|
||||
if (r1 > 0) {
|
||||
p->append_poly();
|
||||
p->insert_vertex(circle1[i].x, circle1[i].y, z1);
|
||||
p->insert_vertex(circle2[i].x, circle2[i].y, z2);
|
||||
p->insert_vertex(circle1[j].x, circle1[j].y, z1);
|
||||
}
|
||||
if (r2 > 0) {
|
||||
p->append_poly();
|
||||
p->insert_vertex(circle2[i].x, circle2[i].y, z2);
|
||||
p->insert_vertex(circle2[j].x, circle2[j].y, z2);
|
||||
p->insert_vertex(circle1[j].x, circle1[j].y, z1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->r1 > 0) {
|
||||
p->append_poly();
|
||||
for (int i=0; i<fragments; i++)
|
||||
p->insert_vertex(circle1[i].x, circle1[i].y, z1);
|
||||
}
|
||||
if (this->r1 > 0) {
|
||||
p->append_poly();
|
||||
for (int i=0; i<fragments; i++)
|
||||
p->insert_vertex(circle1[i].x, circle1[i].y, z1);
|
||||
}
|
||||
|
||||
if (this->r2 > 0) {
|
||||
p->append_poly();
|
||||
for (int i=0; i<fragments; i++)
|
||||
p->append_vertex(circle2[i].x, circle2[i].y, z2);
|
||||
}
|
||||
if (this->r2 > 0) {
|
||||
p->append_poly();
|
||||
for (int i=0; i<fragments; i++)
|
||||
p->append_vertex(circle2[i].x, circle2[i].y, z2);
|
||||
}
|
||||
|
||||
delete[] circle1;
|
||||
delete[] circle2;
|
||||
delete[] circle1;
|
||||
delete[] circle2;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->type == POLYHEDRON)
|
||||
{
|
||||
PolySet *p = new PolySet();
|
||||
break;
|
||||
case POLYHEDRON: {
|
||||
PolySet *p = new PolySet(3);
|
||||
g = p;
|
||||
p->setConvexity(this->convexity);
|
||||
for (size_t i=0; i<this->faces.toVector().size(); i++)
|
||||
|
@ -503,87 +507,89 @@ sphere_next_r2:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->type == SQUARE && this->x > 0 && this->y > 0)
|
||||
{
|
||||
break;
|
||||
case SQUARE: {
|
||||
Polygon2d *p = new Polygon2d();
|
||||
g = p;
|
||||
Vector2d v1(0, 0);
|
||||
Vector2d v2(this->x, this->y);
|
||||
if (this->center) {
|
||||
v1 -= Vector2d(this->x/2, this->y/2);
|
||||
v2 -= Vector2d(this->x/2, this->y/2);
|
||||
}
|
||||
|
||||
Outline2d o;
|
||||
o.vertices.resize(4);
|
||||
o.vertices[0] = v1;
|
||||
o.vertices[1] = Vector2d(v2[0], v1[1]);
|
||||
o.vertices[2] = v2;
|
||||
o.vertices[3] = Vector2d(v1[0], v2[1]);
|
||||
p->addOutline(o);
|
||||
p->setSanitized(true);
|
||||
}
|
||||
|
||||
if (this->type == CIRCLE && this->r1 > 0)
|
||||
{
|
||||
Polygon2d *p = new Polygon2d();
|
||||
g = p;
|
||||
int fragments = Calc::get_fragments_from_r(this->r1, this->fn, this->fs, this->fa);
|
||||
|
||||
Outline2d o;
|
||||
o.vertices.resize(fragments);
|
||||
for (int i=0; i < fragments; i++) {
|
||||
double phi = (M_PI*2*i) / fragments;
|
||||
o.vertices[i] = Vector2d(this->r1*cos(phi), this->r1*sin(phi));
|
||||
}
|
||||
p->addOutline(o);
|
||||
p->setSanitized(true);
|
||||
}
|
||||
|
||||
if (this->type == POLYGON)
|
||||
{
|
||||
Polygon2d *p = new Polygon2d();
|
||||
g = p;
|
||||
|
||||
Outline2d outline;
|
||||
double x,y;
|
||||
const Value::VectorType &vec = this->points.toVector();
|
||||
for (int i=0;i<vec.size();i++) {
|
||||
const Value &val = vec[i];
|
||||
if (!val.getVec2(x, y)) {
|
||||
PRINTB("ERROR: Unable to convert point %s at index %d to a vec2 of numbers",
|
||||
val.toString() % i);
|
||||
delete p;
|
||||
return NULL;
|
||||
if (this->x > 0 && this->y > 0) {
|
||||
Vector2d v1(0, 0);
|
||||
Vector2d v2(this->x, this->y);
|
||||
if (this->center) {
|
||||
v1 -= Vector2d(this->x/2, this->y/2);
|
||||
v2 -= Vector2d(this->x/2, this->y/2);
|
||||
}
|
||||
outline.vertices.push_back(Vector2d(x, y));
|
||||
}
|
||||
|
||||
if (this->paths.toVector().size() == 0 && outline.vertices.size() > 2) {
|
||||
p->addOutline(outline);
|
||||
Outline2d o;
|
||||
o.vertices.resize(4);
|
||||
o.vertices[0] = v1;
|
||||
o.vertices[1] = Vector2d(v2[0], v1[1]);
|
||||
o.vertices[2] = v2;
|
||||
o.vertices[3] = Vector2d(v1[0], v2[1]);
|
||||
p->addOutline(o);
|
||||
p->setSanitized(true);
|
||||
}
|
||||
else {
|
||||
BOOST_FOREACH(const Value &polygon, this->paths.toVector()) {
|
||||
Outline2d curroutline;
|
||||
BOOST_FOREACH(const Value &index, polygon.toVector()) {
|
||||
unsigned int idx = index.toDouble();
|
||||
if (idx < outline.vertices.size()) {
|
||||
curroutline.vertices.push_back(outline.vertices[idx]);
|
||||
}
|
||||
// FIXME: Warning on out of bounds?
|
||||
}
|
||||
break;
|
||||
case CIRCLE: {
|
||||
Polygon2d *p = new Polygon2d();
|
||||
g = p;
|
||||
if (this->r1 > 0) {
|
||||
int fragments = Calc::get_fragments_from_r(this->r1, this->fn, this->fs, this->fa);
|
||||
|
||||
Outline2d o;
|
||||
o.vertices.resize(fragments);
|
||||
for (int i=0; i < fragments; i++) {
|
||||
double phi = (M_PI*2*i) / fragments;
|
||||
o.vertices[i] = Vector2d(this->r1*cos(phi), this->r1*sin(phi));
|
||||
}
|
||||
p->addOutline(o);
|
||||
p->setSanitized(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case POLYGON: {
|
||||
Polygon2d *p = new Polygon2d();
|
||||
g = p;
|
||||
|
||||
Outline2d outline;
|
||||
double x,y;
|
||||
const Value::VectorType &vec = this->points.toVector();
|
||||
for (int i=0;i<vec.size();i++) {
|
||||
const Value &val = vec[i];
|
||||
if (!val.getVec2(x, y)) {
|
||||
PRINTB("ERROR: Unable to convert point %s at index %d to a vec2 of numbers",
|
||||
val.toString() % i);
|
||||
delete p;
|
||||
return NULL;
|
||||
}
|
||||
outline.vertices.push_back(Vector2d(x, y));
|
||||
}
|
||||
|
||||
if (this->paths.toVector().size() == 0 && outline.vertices.size() > 2) {
|
||||
p->addOutline(outline);
|
||||
}
|
||||
else {
|
||||
BOOST_FOREACH(const Value &polygon, this->paths.toVector()) {
|
||||
Outline2d curroutline;
|
||||
BOOST_FOREACH(const Value &index, polygon.toVector()) {
|
||||
unsigned int idx = index.toDouble();
|
||||
if (idx < outline.vertices.size()) {
|
||||
curroutline.vertices.push_back(outline.vertices[idx]);
|
||||
}
|
||||
// FIXME: Warning on out of bounds?
|
||||
}
|
||||
p->addOutline(curroutline);
|
||||
}
|
||||
p->addOutline(curroutline);
|
||||
}
|
||||
}
|
||||
|
||||
if (p->outlines().size() == 0) {
|
||||
delete p;
|
||||
g = NULL;
|
||||
}
|
||||
else {
|
||||
p->setConvexity(convexity);
|
||||
}
|
||||
if (p->outlines().size() == 0) {
|
||||
delete p;
|
||||
g = NULL;
|
||||
}
|
||||
else {
|
||||
p->setConvexity(convexity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return g;
|
||||
|
|
|
@ -108,7 +108,7 @@ Geometry *SurfaceNode::createGeometry() const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
PolySet *p = new PolySet();
|
||||
PolySet *p = new PolySet(3);
|
||||
int lines = 0, columns = 0;
|
||||
boost::unordered_map<std::pair<int,int>,double> data;
|
||||
double min_val = 0;
|
||||
|
|
|
@ -556,7 +556,6 @@ set(CGAL_SOURCES
|
|||
../src/cgalutils.cc
|
||||
../src/CGALCache.cc
|
||||
../src/CGAL_Nef_polyhedron_DxfData.cc
|
||||
../src/cgaladv_minkowski2.cc
|
||||
../src/Polygon2d-CGAL.cc
|
||||
../src/polyset-utils.cc
|
||||
../src/svg.cc
|
||||
|
|
Loading…
Reference in New Issue