diff --git a/main/Scene-load.cc b/main/Scene-load.cc index 29714aa..41a1765 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -61,6 +61,10 @@ void Scene::processNode(refptr node) { processMaterialDefinition(node); } + else if ( typeid(*node) == typeid(ShapeDefinitionNode) ) + { + processShapeDefinition(node); + } else { cerr << __FILE__ << ": " << __LINE__ @@ -143,6 +147,10 @@ refptr Scene::processShape(refptr node) { return processExtrude(node); } + else if ( typeid(*node) == typeid(ShapeRefNode) ) + { + return processShapeRef(node); + } return refptr(NULL); } @@ -659,6 +667,20 @@ refptr Scene::processNGon(refptr node) return p; } +refptr Scene::processShapeRef(refptr node) +{ + if (m_shape_definitions.find(node->getString()) + != m_shape_definitions.end()) + { + refptr shape = m_shape_definitions[node->getString()]->clone(); + shape->setTransform(m_transforms.top()); + return shape; + } + cerr << "Error: no shape definition for '" << node->getString() + << "' found!" << endl; + exit(3); +} + bool Scene::processTransforms(refptr node) { bool did_any = false; @@ -699,3 +721,9 @@ bool Scene::processTransforms(refptr node) return did_any; } + +void Scene::processShapeDefinition(refptr node) +{ + m_shape_definitions[node->getString()] + = processShape(node->getChildren()[0]); +} diff --git a/main/Scene.h b/main/Scene.h index b039683..e7f4d03 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -70,6 +70,7 @@ class Scene refptr processShape(refptr node); refptr processBool(refptr node); refptr processExtrude(refptr node); + refptr processShapeRef(refptr node); refptr processPolygon(refptr node); refptr processNGon(refptr node); bool processTransforms(refptr node); @@ -77,6 +78,7 @@ class Scene void processOptions(refptr node); void processTransformBlock(refptr node); void processMaterialDefinition(refptr node); + void processShapeDefinition(refptr node); /* rendering parameters */ int m_width; @@ -90,7 +92,7 @@ class Scene /* private data */ std::vector< refptr > m_shapes; - std::vector< refptr > m_shape_definitions; + std::map< std::string, refptr > m_shape_definitions; std::vector< refptr > m_lights; std::stack m_transforms; double m_view_plane_dist; diff --git a/shapes/BoolShape.cc b/shapes/BoolShape.cc index 3695963..a8e27b0 100644 --- a/shapes/BoolShape.cc +++ b/shapes/BoolShape.cc @@ -7,3 +7,11 @@ void BoolShape::setMaterial(refptr material) m_shape1->setMaterial(material); m_shape2->setMaterial(material); } + +void BoolShape::setTransform(Transform & t) +{ + m_transform = t; + m_inverse = t.getInverse(); + m_shape1->setTransform(t); + m_shape2->setTransform(t); +} diff --git a/shapes/BoolShape.h b/shapes/BoolShape.h index c633906..e2a66df 100644 --- a/shapes/BoolShape.h +++ b/shapes/BoolShape.h @@ -9,6 +9,8 @@ class BoolShape : public Shape public: virtual IntersectionList intersect(refptr _this, const Ray & ray) = 0; virtual void setMaterial(refptr material); + virtual void setTransform(Transform & t); + virtual refptr clone() = 0; protected: refptr m_shape1; diff --git a/shapes/Box.cc b/shapes/Box.cc index 5e2fb8c..5a77263 100644 --- a/shapes/Box.cc +++ b/shapes/Box.cc @@ -70,3 +70,8 @@ Shape::IntersectionList Box::intersect(refptr _this, const Ray & ray) return res; } + +refptr Box::clone() +{ + return new Box(*this); +} diff --git a/shapes/Box.h b/shapes/Box.h index d86b03f..c474be7 100644 --- a/shapes/Box.h +++ b/shapes/Box.h @@ -9,6 +9,7 @@ class Box : public Shape public: Box(refptr size); IntersectionList intersect(refptr _this, const Ray & ray); + virtual refptr clone(); protected: Vector m_size; diff --git a/shapes/Cyl.cc b/shapes/Cyl.cc index df40f8c..bb4ec33 100644 --- a/shapes/Cyl.cc +++ b/shapes/Cyl.cc @@ -134,3 +134,8 @@ Shape::IntersectionList Cyl::intersect(refptr _this, const Ray & ray) return res; } + +refptr Cyl::clone() +{ + return new Cyl(*this); +} diff --git a/shapes/Cyl.h b/shapes/Cyl.h index 37714b0..f0873c5 100644 --- a/shapes/Cyl.h +++ b/shapes/Cyl.h @@ -9,6 +9,7 @@ class Cyl : public Shape public: Cyl(double bottom_radius, double top_radius, double height); IntersectionList intersect(refptr _this, const Ray & ray); + virtual refptr clone(); protected: double m_bottom_radius; diff --git a/shapes/Extrude.cc b/shapes/Extrude.cc index a0876ee..7924d2b 100644 --- a/shapes/Extrude.cc +++ b/shapes/Extrude.cc @@ -166,3 +166,8 @@ void Extrude::addOffset(double distance, { m_offsets.push_back(Offset(distance, scale, shift)); } + +refptr Extrude::clone() +{ + return new Extrude(*this); +} diff --git a/shapes/Extrude.h b/shapes/Extrude.h index 02c895e..ac9c9a5 100644 --- a/shapes/Extrude.h +++ b/shapes/Extrude.h @@ -26,6 +26,7 @@ class Extrude : public Shape Vector scale; Vector shift; }; + virtual refptr clone(); protected: std::vector< refptr > m_polygons; diff --git a/shapes/Intersect.cc b/shapes/Intersect.cc index dd343dd..b8adbf7 100644 --- a/shapes/Intersect.cc +++ b/shapes/Intersect.cc @@ -98,3 +98,11 @@ Shape::IntersectionList Intersect::intersect(refptr _this, const Ray & ra return res; } + +refptr Intersect::clone() +{ + Intersect * s = new Intersect(*this); + s->m_shape1 = m_shape1->clone(); + s->m_shape2 = m_shape2->clone(); + return refptr(s); +} diff --git a/shapes/Intersect.h b/shapes/Intersect.h index f958882..6d33d8a 100644 --- a/shapes/Intersect.h +++ b/shapes/Intersect.h @@ -10,6 +10,7 @@ class Intersect : public BoolShape public: Intersect(const std::vector< refptr > & shapes); IntersectionList intersect(refptr _this, const Ray & ray); + refptr clone(); }; #endif diff --git a/shapes/Plane.cc b/shapes/Plane.cc index 74f9769..b3afbc0 100644 --- a/shapes/Plane.cc +++ b/shapes/Plane.cc @@ -50,3 +50,8 @@ Shape::IntersectionList Plane::intersect(refptr _this, const Ray & ray) } return res; } + +refptr Plane::clone() +{ + return new Plane(*this); +} diff --git a/shapes/Plane.h b/shapes/Plane.h index 94c3a01..73aeec1 100644 --- a/shapes/Plane.h +++ b/shapes/Plane.h @@ -9,6 +9,7 @@ class Plane : public Shape public: Plane(double a, double b, double c, double d); IntersectionList intersect(refptr _this, const Ray & ray); + virtual refptr clone(); protected: double m_a, m_b, m_c, m_d; diff --git a/shapes/Shape.h b/shapes/Shape.h index 50a65ff..72025af 100644 --- a/shapes/Shape.h +++ b/shapes/Shape.h @@ -101,8 +101,9 @@ class Shape virtual ~Shape(); virtual IntersectionList intersect(refptr _this, const Ray & ray) = 0; + virtual refptr clone() = 0; - void setTransform(Transform & t) + virtual void setTransform(Transform & t) { m_transform = t; m_inverse = t.getInverse(); diff --git a/shapes/Sphere.cc b/shapes/Sphere.cc index d98e89f..1f6925a 100644 --- a/shapes/Sphere.cc +++ b/shapes/Sphere.cc @@ -41,3 +41,8 @@ Shape::IntersectionList Sphere::intersect(refptr _this, const Ray & ray) } return res; } + +refptr Sphere::clone() +{ + return new Sphere(*this); +} diff --git a/shapes/Sphere.h b/shapes/Sphere.h index 9b83404..19ce427 100644 --- a/shapes/Sphere.h +++ b/shapes/Sphere.h @@ -9,6 +9,7 @@ class Sphere : public Shape public: Sphere(double radius); IntersectionList intersect(refptr _this, const Ray & ray); + virtual refptr clone(); protected: double m_radius; diff --git a/shapes/Subtract.cc b/shapes/Subtract.cc index ec22725..a61f6de 100644 --- a/shapes/Subtract.cc +++ b/shapes/Subtract.cc @@ -98,3 +98,11 @@ Shape::IntersectionList Subtract::intersect(refptr _this, const Ray & ray return res; } + +refptr Subtract::clone() +{ + Subtract * s = new Subtract(*this); + s->m_shape1 = m_shape1->clone(); + s->m_shape2 = m_shape2->clone(); + return refptr(s); +} diff --git a/shapes/Subtract.h b/shapes/Subtract.h index 9697b8b..5faf573 100644 --- a/shapes/Subtract.h +++ b/shapes/Subtract.h @@ -10,6 +10,7 @@ class Subtract : public BoolShape public: Subtract(const std::vector< refptr > & shapes); IntersectionList intersect(refptr _this, const Ray & ray); + refptr clone(); }; #endif diff --git a/shapes/Union.cc b/shapes/Union.cc index 07d7af6..5000b33 100644 --- a/shapes/Union.cc +++ b/shapes/Union.cc @@ -99,3 +99,11 @@ Shape::IntersectionList Union::intersect(refptr _this, const Ray & ray) return res; } + +refptr Union::clone() +{ + Union * s = new Union(*this); + s->m_shape1 = m_shape1->clone(); + s->m_shape2 = m_shape2->clone(); + return refptr(s); +} diff --git a/shapes/Union.h b/shapes/Union.h index e332990..90af728 100644 --- a/shapes/Union.h +++ b/shapes/Union.h @@ -10,6 +10,7 @@ class Union : public BoolShape public: Union(const std::vector< refptr > & shapes); IntersectionList intersect(refptr _this, const Ray & ray); + refptr clone(); }; #endif