mirror of https://github.com/vitalif/openscad
Allow the state to track cache lookup preference. This is important to allow lookups to prefer Nef polyhedrons in cases where PolySet->Nef fails due to zero triangles. Fixes #1027
parent
ceb01a3ef2
commit
083bf4313f
|
@ -366,14 +366,17 @@ void GeometryEvaluator::addToParent(const State &state,
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const AbstractNode &node)
|
Response GeometryEvaluator::visit(State &state, const AbstractNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
if (state.isPrefix()) {
|
||||||
|
if (isSmartCached(node)) return PruneTraversal;
|
||||||
|
state.setPreferNef(true); // Improve quality of CSG by avoiding conversion loss
|
||||||
|
}
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const class Geometry> geom;
|
shared_ptr<const class Geometry> geom;
|
||||||
if (!isSmartCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
geom = applyToChildren(node, OPENSCAD_UNION).constptr();
|
geom = applyToChildren(node, OPENSCAD_UNION).constptr();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, state.preferNef());
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -400,7 +403,7 @@ Response GeometryEvaluator::visit(State &state, const OffsetNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, false);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -412,7 +415,10 @@ Response GeometryEvaluator::visit(State &state, const OffsetNode &node)
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const RenderNode &node)
|
Response GeometryEvaluator::visit(State &state, const RenderNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
if (state.isPrefix()) {
|
||||||
|
if (isSmartCached(node)) return PruneTraversal;
|
||||||
|
state.setPreferNef(true); // Improve quality of CSG by avoiding conversion loss
|
||||||
|
}
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const class Geometry> geom;
|
shared_ptr<const class Geometry> geom;
|
||||||
if (!isSmartCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
|
@ -437,7 +443,7 @@ Response GeometryEvaluator::visit(State &state, const RenderNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, state.preferNef());
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -466,7 +472,7 @@ Response GeometryEvaluator::visit(State &state, const LeafNode &node)
|
||||||
}
|
}
|
||||||
geom.reset(geometry);
|
geom.reset(geometry);
|
||||||
}
|
}
|
||||||
else geom = smartCacheGet(node);
|
else geom = smartCacheGet(node, state.preferNef());
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
return PruneTraversal;
|
return PruneTraversal;
|
||||||
|
@ -501,14 +507,17 @@ Response GeometryEvaluator::visit(State &state, const TextNode &node)
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const CsgNode &node)
|
Response GeometryEvaluator::visit(State &state, const CsgNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
if (state.isPrefix()) {
|
||||||
|
if (isSmartCached(node)) return PruneTraversal;
|
||||||
|
state.setPreferNef(true); // Improve quality of CSG by avoiding conversion loss
|
||||||
|
}
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const Geometry> geom;
|
shared_ptr<const Geometry> geom;
|
||||||
if (!isSmartCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
geom = applyToChildren(node, node.type).constptr();
|
geom = applyToChildren(node, node.type).constptr();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, state.preferNef());
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -583,7 +592,7 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, state.preferNef());
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -736,7 +745,7 @@ Response GeometryEvaluator::visit(State &state, const LinearExtrudeNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, false);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -844,7 +853,7 @@ Response GeometryEvaluator::visit(State &state, const RotateExtrudeNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, false);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -962,7 +971,7 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, false);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -1038,7 +1047,7 @@ Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, state.preferNef());
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -1047,14 +1056,17 @@ Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
|
||||||
|
|
||||||
Response GeometryEvaluator::visit(State &state, const AbstractIntersectionNode &node)
|
Response GeometryEvaluator::visit(State &state, const AbstractIntersectionNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
if (state.isPrefix()) {
|
||||||
|
if (isSmartCached(node)) return PruneTraversal;
|
||||||
|
state.setPreferNef(true); // Improve quality of CSG by avoiding conversion loss
|
||||||
|
}
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const class Geometry> geom;
|
shared_ptr<const class Geometry> geom;
|
||||||
if (!isSmartCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
geom = applyToChildren(node, OPENSCAD_INTERSECTION).constptr();
|
geom = applyToChildren(node, OPENSCAD_INTERSECTION).constptr();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = smartCacheGet(node);
|
geom = smartCacheGet(node, state.preferNef());
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void smartCacheInsert(const AbstractNode &node, const shared_ptr<const Geometry> &geom);
|
void smartCacheInsert(const AbstractNode &node, const shared_ptr<const Geometry> &geom);
|
||||||
shared_ptr<const Geometry> smartCacheGet(const AbstractNode &node, bool preferNef = false);
|
shared_ptr<const Geometry> smartCacheGet(const AbstractNode &node, bool preferNef);
|
||||||
bool isSmartCached(const AbstractNode &node);
|
bool isSmartCached(const AbstractNode &node);
|
||||||
std::vector<const class Polygon2d *> collectChildren2D(const AbstractNode &node);
|
std::vector<const class Polygon2d *> collectChildren2D(const AbstractNode &node);
|
||||||
Geometry::ChildList collectChildren3D(const AbstractNode &node);
|
Geometry::ChildList collectChildren3D(const AbstractNode &node);
|
||||||
|
|
|
@ -7,7 +7,7 @@ class State
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
State(const class AbstractNode *parent)
|
State(const class AbstractNode *parent)
|
||||||
: parentnode(parent), isprefix(false), ispostfix(false), numchildren(0) {
|
: parentnode(parent), isprefix(false), ispostfix(false), numchildren(0), prefernef(false) {
|
||||||
this->matrix_ = Transform3d::Identity();
|
this->matrix_ = Transform3d::Identity();
|
||||||
this->color_.fill(-1.0f);
|
this->color_.fill(-1.0f);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ public:
|
||||||
void setParent(const AbstractNode *parent) { this->parentnode = parent; }
|
void setParent(const AbstractNode *parent) { this->parentnode = parent; }
|
||||||
void setMatrix(const Transform3d &m) { this->matrix_ = m; }
|
void setMatrix(const Transform3d &m) { this->matrix_ = m; }
|
||||||
void setColor(const Color4f &c) { this->color_ = c; }
|
void setColor(const Color4f &c) { this->color_ = c; }
|
||||||
|
void setPreferNef(bool on) { this->prefernef = on; }
|
||||||
|
bool preferNef() const { return this->prefernef; }
|
||||||
|
|
||||||
bool isPrefix() const { return this->isprefix; }
|
bool isPrefix() const { return this->isprefix; }
|
||||||
bool isPostfix() const { return this->ispostfix; }
|
bool isPostfix() const { return this->ispostfix; }
|
||||||
|
@ -33,6 +35,7 @@ private:
|
||||||
bool ispostfix;
|
bool ispostfix;
|
||||||
unsigned int numchildren;
|
unsigned int numchildren;
|
||||||
|
|
||||||
|
bool prefernef;
|
||||||
// Transformation matrix and color. FIXME: Generalize such state variables?
|
// Transformation matrix and color. FIXME: Generalize such state variables?
|
||||||
Transform3d matrix_;
|
Transform3d matrix_;
|
||||||
Color4f color_;
|
Color4f color_;
|
||||||
|
|
Loading…
Reference in New Issue