minkowski sums should now work again

stl_dim
Marius Kintel 2011-09-06 14:57:24 +02:00
parent fdd96a177c
commit 1e4e18c524
10 changed files with 128 additions and 84 deletions

View File

@ -142,6 +142,7 @@ HEADERS += src/renderer.h \
src/dxflinextrudenode.h \
src/dxfrotextrudenode.h \
src/projectionnode.h \
src/cgaladvnode.h \
src/importnode.h \
src/transformnode.h \
src/colornode.h \

View File

@ -5,6 +5,7 @@
#include "printutils.h"
#include "csgnode.h"
#include "cgaladvnode.h"
#include "transformnode.h"
#include "polyset.h"
#include "dxfdata.h"
@ -47,7 +48,7 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr
assert(false && "Dimension of Nef polyhedron must be 2 or 3");
}
if (src.empty()) return; // Empty polyhedron. This can happen for e.g. square([0,0])
assert(target.dim == src.dim);
if (target.dim != src.dim) return; // If someone tries to e.g. union 2d and 3d objects
switch (op) {
case CGE_UNION:
@ -203,14 +204,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node)
}
// FIXME: EvaluateNode: Union over children + some magic
// FIXME: CgaladvNode: Iterate over children. Special operation
// FIXME: Subtypes of AbstractPolyNode:
// ProjectionNode
// DxfLinearExtrudeNode
// DxfRotateExtrudeNode
// (SurfaceNode)
// (PrimitiveNode)
Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node)
{
if (state.isPrefix() && isCached(node)) return PruneTraversal;
@ -242,6 +236,32 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node)
return ContinueTraversal;
}
Response CGALEvaluator::visit(State &state, const CgaladvNode &node)
{
if (state.isPrefix() && isCached(node)) return PruneTraversal;
if (state.isPostfix()) {
if (!isCached(node)) {
CGALEvaluator::CsgOp op;
switch (node.type) {
case MINKOWSKI:
op = CGE_MINKOWSKI;
break;
case GLIDE:
case SUBDIV:
// FIXME: Not implemented
return PruneTraversal;
break;
case HULL:
op = CGE_HULL;
break;
}
applyToChildren(node, op);
}
addToParent(state, node);
}
return ContinueTraversal;
}
/*!
Adds ourself to out parent's list of traversed children.
Call this for _every_ node which affects output during the postfix traversal.

View File

@ -29,6 +29,7 @@ public:
virtual Response visit(State &state, const CsgNode &node);
virtual Response visit(State &state, const TransformNode &node);
virtual Response visit(State &state, const AbstractPolyNode &node);
virtual Response visit(State &state, const CgaladvNode &node);
CGAL_Nef_polyhedron evaluateCGALMesh(const AbstractNode &node);
CGAL_Nef_polyhedron evaluateCGALMesh(const PolySet &polyset);

View File

@ -1,6 +1,8 @@
#include "CGAL_Nef_polyhedron.h"
#include "cgal.h"
#include "polyset.h"
#include "dxfdata.h"
#include "dxftess.h"
#include <CGAL/minkowski_sum_3.h>
CGAL_Nef_polyhedron& CGAL_Nef_polyhedron::operator+=(const CGAL_Nef_polyhedron &other)
@ -48,38 +50,48 @@ int CGAL_Nef_polyhedron::weight() const
*/
PolySet *CGAL_Nef_polyhedron::convertToPolyset()
{
assert(!this->empty());
PolySet *ps = new PolySet();
CGAL_Polyhedron P;
this->p3->convert_to_Polyhedron(P);
typedef CGAL_Polyhedron::Vertex Vertex;
typedef CGAL_Polyhedron::Vertex_const_iterator VCI;
typedef CGAL_Polyhedron::Facet_const_iterator FCI;
typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC;
for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) {
HFCC hc = fi->facet_begin();
HFCC hc_end = hc;
Vertex v1, v2, v3;
v1 = *VCI((hc++)->vertex());
v3 = *VCI((hc++)->vertex());
do {
v2 = v3;
if (this->dim == 2) {
DxfData *dd = this->convertToDxfData();
ps->is2d = true;
dxf_tesselate(ps, *dd, 0, true, false, 0);
dxf_border_to_ps(ps, *dd);
delete dd;
}
else if (this->dim == 3) {
CGAL_Polyhedron P;
this->p3->convert_to_Polyhedron(P);
typedef CGAL_Polyhedron::Vertex Vertex;
typedef CGAL_Polyhedron::Vertex_const_iterator VCI;
typedef CGAL_Polyhedron::Facet_const_iterator FCI;
typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC;
for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) {
HFCC hc = fi->facet_begin();
HFCC hc_end = hc;
Vertex v1, v2, v3;
v1 = *VCI((hc++)->vertex());
v3 = *VCI((hc++)->vertex());
double x1 = CGAL::to_double(v1.point().x());
double y1 = CGAL::to_double(v1.point().y());
double z1 = CGAL::to_double(v1.point().z());
double x2 = CGAL::to_double(v2.point().x());
double y2 = CGAL::to_double(v2.point().y());
double z2 = CGAL::to_double(v2.point().z());
double x3 = CGAL::to_double(v3.point().x());
double y3 = CGAL::to_double(v3.point().y());
double z3 = CGAL::to_double(v3.point().z());
ps->append_poly();
ps->append_vertex(x1, y1, z1);
ps->append_vertex(x2, y2, z2);
ps->append_vertex(x3, y3, z3);
} while (hc != hc_end);
do {
v2 = v3;
v3 = *VCI((hc++)->vertex());
double x1 = CGAL::to_double(v1.point().x());
double y1 = CGAL::to_double(v1.point().y());
double z1 = CGAL::to_double(v1.point().z());
double x2 = CGAL::to_double(v2.point().x());
double y2 = CGAL::to_double(v2.point().y());
double z2 = CGAL::to_double(v2.point().z());
double x3 = CGAL::to_double(v3.point().x());
double y3 = CGAL::to_double(v3.point().y());
double z3 = CGAL::to_double(v3.point().z());
ps->append_poly();
ps->append_vertex(x1, y1, z1);
ps->append_vertex(x2, y2, z2);
ps->append_vertex(x3, y3, z3);
} while (hc != hc_end);
}
}
return ps;
}

View File

@ -7,7 +7,9 @@
#include "transformnode.h"
#include "colornode.h"
#include "rendernode.h"
#include "cgaladvnode.h"
#include "printutils.h"
#include "PolySetEvaluator.h"
#include <string>
#include <map>
@ -88,7 +90,7 @@ static CSGTerm *evaluate_csg_term_from_ps(const State &state,
vector<CSGTerm*> &background,
PolySet *ps,
const ModuleInstantiation *modinst,
const AbstractPolyNode &node)
const AbstractNode &node)
{
std::stringstream stream;
stream << node.name() << node.index();
@ -184,6 +186,25 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node)
return ContinueTraversal;
}
Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node)
{
if (state.isPostfix()) {
CSGTerm *t1 = NULL;
// FIXME: Calling evaluator directly since we're not a PolyNode. Generalize this.
PolySet *ps = NULL;
if (this->psevaluator) {
ps = this->psevaluator->evaluatePolySet(node, AbstractPolyNode::RENDER_OPENCSG);
}
if (ps) {
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,
ps, node.modinst, node);
}
this->stored_term[node.index()] = t1;
addToParent(state, node);
}
return ContinueTraversal;
}
/*!
Adds ourself to out parent's list of traversed children.
Call this for _every_ node which affects output during the postfix traversal.

View File

@ -29,6 +29,7 @@ public:
virtual Response visit(State &state, const TransformNode &node);
virtual Response visit(State &state, const ColorNode &node);
virtual Response visit(State &state, const RenderNode &node);
virtual Response visit(State &state, const CgaladvNode &node);
class CSGTerm *evaluateCSGTerm(const AbstractNode &node,
vector<CSGTerm*> &highlights,

View File

@ -5,6 +5,7 @@
#include "projectionnode.h"
#include "dxflinextrudenode.h"
#include "dxfrotextrudenode.h"
#include "cgaladvnode.h"
#include "dxfdata.h"
#include "dxftess.h"
#include "module.h"
@ -367,6 +368,15 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const DxfRotateExtrudeNode &node,
return ps;
}
PolySet *PolySetCGALEvaluator::evaluatePolySet(const CgaladvNode &node, AbstractPolyNode::render_mode_e)
{
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node);
PolySet *ps = NULL;
if (!N.empty()) ps = N.convertToPolyset();
return ps;
}
PolySet *PolySetCGALEvaluator::rotateDxfData(const DxfRotateExtrudeNode &node, DxfData &dxf)
{
PolySet *ps = new PolySet();

View File

@ -16,6 +16,7 @@ public:
virtual PolySet *evaluatePolySet(const ProjectionNode &node, AbstractPolyNode::render_mode_e);
virtual PolySet *evaluatePolySet(const DxfLinearExtrudeNode &node, AbstractPolyNode::render_mode_e);
virtual PolySet *evaluatePolySet(const DxfRotateExtrudeNode &node, AbstractPolyNode::render_mode_e);
virtual PolySet *evaluatePolySet(const CgaladvNode &node, AbstractPolyNode::render_mode_e);
protected:
PolySet *extrudeDxfData(const DxfLinearExtrudeNode &node, class DxfData &dxf);

View File

@ -16,6 +16,7 @@ public:
virtual PolySet *evaluatePolySet(const class ProjectionNode &, AbstractPolyNode::render_mode_e) = 0;
virtual PolySet *evaluatePolySet(const class DxfLinearExtrudeNode &, AbstractPolyNode::render_mode_e) = 0;
virtual PolySet *evaluatePolySet(const class DxfRotateExtrudeNode &, AbstractPolyNode::render_mode_e) = 0;
virtual PolySet *evaluatePolySet(const class CgaladvNode &, AbstractPolyNode::render_mode_e) = 0;
void clearCache() {
this->cache.clear();

View File

@ -24,24 +24,16 @@
*
*/
#include "cgaladvnode.h"
#include "module.h"
#include "node.h"
#include "context.h"
#include "builtin.h"
#include "printutils.h"
#include "visitor.h"
#include <sstream>
#include <assert.h>
#include <boost/assign/std/vector.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope
enum cgaladv_type_e {
MINKOWSKI,
GLIDE,
SUBDIV,
HULL
};
class CgaladvModule : public AbstractModule
{
public:
@ -50,42 +42,6 @@ public:
virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const;
};
class CgaladvNode : public AbstractNode
{
public:
CgaladvNode(const ModuleInstantiation *mi, cgaladv_type_e type) : AbstractNode(mi), type(type) {
convexity = 1;
}
virtual ~CgaladvNode() { }
virtual Response accept(class State &state, Visitor &visitor) const {
return visitor.visit(state, *this);
}
virtual std::string toString() const;
virtual std::string name() const {
switch (this->type) {
case MINKOWSKI:
return "minkowski";
break;
case GLIDE:
return "glide";
break;
case SUBDIV:
return "subdiv";
break;
case HULL:
return "hull";
break;
default:
assert(false);
}
}
Value path;
std::string subdiv_type;
int convexity, level;
cgaladv_type_e type;
};
AbstractNode *CgaladvModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const
{
CgaladvNode *node = new CgaladvNode(inst, type);
@ -144,6 +100,26 @@ void register_builtin_cgaladv()
builtin_modules["hull"] = new CgaladvModule(HULL);
}
std::string CgaladvNode::name() const
{
switch (this->type) {
case MINKOWSKI:
return "minkowski";
break;
case GLIDE:
return "glide";
break;
case SUBDIV:
return "subdiv";
break;
case HULL:
return "hull";
break;
default:
assert(false);
}
}
std::string CgaladvNode::toString() const
{
std::stringstream stream;