00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef INSIDE_LIST_EXPRESSION_HPP
00021 #define INSIDE_LIST_EXPRESSION_HPP
00022
00023 #include <Expression.hpp>
00024 #include <InsideExpression.hpp>
00025
00026 #include <Stringify.hpp>
00027 #include <ErrorHandler.hpp>
00028
00029 class Object;
00030 class Scene;
00031
00041 class InsideListExpression
00042 : public Expression
00043 {
00044 protected:
00045
00046 typedef std::map<TinyVector<3, real_t>, size_t> ReferenceList;
00047
00048 public:
00049 enum NodeType {
00050 NodeAnd,
00051 NodeOr,
00052 NodeNot,
00053 NodeLeaf
00054 };
00055
00056 private:
00057 const NodeType __type;
00059 public:
00060
00065 void execute()
00066 {
00067 this->subExecute();
00068 this->checkReferencesUniqueness();
00069 }
00070
00075 virtual void subExecute() = 0;
00076
00081 void checkReferencesUniqueness()
00082 {
00083 InsideListExpression::ReferenceList references;
00084 this->addReferences(references);
00085 for (ReferenceList::const_iterator i = references.begin();
00086 i != references.end(); ++i) {
00087 if ((*i).second > 1) {
00088 std::string errorMsg
00089 = "POV-Ray reference "+stringify((*i).first)+" is used "
00090 +stringify((*i).second)+" times in the domain definition\n"
00091 "only once is allowed";
00092 throw ErrorHandler(__FILE__,__LINE__,
00093 errorMsg,
00094 ErrorHandler::normal);
00095 }
00096 }
00097 }
00098
00105 virtual void
00106 addReferences(InsideListExpression::ReferenceList& references) = 0;
00107
00113 virtual ReferenceCounting<Object> objects(const Scene& S) = 0;
00114
00121 InsideListExpression(const InsideListExpression::NodeType type)
00122 : Expression(Expression::insideListExpression),
00123 __type(type)
00124 {
00125 ;
00126 }
00127
00134 InsideListExpression(const InsideListExpression& ie)
00135 : Expression(ie),
00136 __type(ie.__type)
00137 {
00138 ;
00139 }
00140
00146 virtual ~InsideListExpression()
00147 {
00148 ;
00149 }
00150 };
00151
00152
00153 class InsideListExpressionAnd
00154 : public InsideListExpression
00155 {
00156 private:
00157
00158 ReferenceCounting<InsideListExpression> __node1;
00159
00160 ReferenceCounting<InsideListExpression> __node2;
00161
00168 std::ostream& put(std::ostream& os) const
00169 {
00170 os << '(' << *__node1 << " and " << *__node2 << ')';
00171 return os;
00172 }
00173
00174 public:
00175
00176 ReferenceCounting<Object> objects(const Scene& S);
00177
00182 void subExecute()
00183 {
00184 (*__node1).subExecute();
00185 (*__node2).subExecute();
00186 }
00187
00194 void
00195 addReferences(InsideListExpression::ReferenceList& references)
00196 {
00197 (*__node1).addReferences(references);
00198 (*__node2).addReferences(references);
00199 }
00200
00208 InsideListExpressionAnd(ReferenceCounting<InsideListExpression> node1,
00209 ReferenceCounting<InsideListExpression> node2)
00210 : InsideListExpression(InsideListExpression::NodeAnd),
00211 __node1(node1),
00212 __node2(node2)
00213 {
00214 ;
00215 }
00216
00223 InsideListExpressionAnd(const InsideListExpressionAnd& I)
00224 : InsideListExpression(I),
00225 __node1(I.__node1),
00226 __node2(I.__node2)
00227 {
00228 ;
00229 }
00230
00235 ~InsideListExpressionAnd()
00236 {
00237 ;
00238 }
00239 };
00240
00241
00242 class InsideListExpressionOr
00243 : public InsideListExpression
00244 {
00245 private:
00246
00247 ReferenceCounting<InsideListExpression> __node1;
00248
00249 ReferenceCounting<InsideListExpression> __node2;
00250
00257 std::ostream& put(std::ostream& os) const
00258 {
00259 os << '(' << *__node1 << " or " << *__node2 << ')';
00260 return os;
00261 }
00262
00263 public:
00264 ReferenceCounting<Object> objects(const Scene& S);
00265
00270 void subExecute()
00271 {
00272 (*__node1).subExecute();
00273 (*__node2).subExecute();
00274 }
00275
00282 void
00283 addReferences(InsideListExpression::ReferenceList& references)
00284 {
00285 (*__node1).addReferences(references);
00286 (*__node2).addReferences(references);
00287 }
00288
00296 InsideListExpressionOr(ReferenceCounting<InsideListExpression> node1,
00297 ReferenceCounting<InsideListExpression> node2)
00298 : InsideListExpression(InsideListExpression::NodeOr),
00299 __node1(node1),
00300 __node2(node2)
00301 {
00302 ;
00303 }
00304
00311 InsideListExpressionOr(const InsideListExpressionOr& I)
00312 : InsideListExpression(I),
00313 __node1(I.__node1),
00314 __node2(I.__node2)
00315 {
00316 ;
00317 }
00318
00323 ~InsideListExpressionOr()
00324 {
00325 ;
00326 }
00327 };
00328
00329
00330
00331 class InsideListExpressionNot
00332 : public InsideListExpression
00333 {
00334 private:
00335
00336 ReferenceCounting<InsideListExpression> __node;
00337
00344 std::ostream& put(std::ostream& os) const
00345 {
00346 os << '!' << *__node;
00347 return os;
00348 }
00349
00350 public:
00351
00352 ReferenceCounting<Object> objects(const Scene& S);
00353
00358 void subExecute()
00359 {
00360 (*__node).subExecute();
00361 }
00362
00369 void
00370 addReferences(InsideListExpression::ReferenceList& references)
00371 {
00372 (*__node).addReferences(references);
00373 }
00374
00381 InsideListExpressionNot(ReferenceCounting<InsideListExpression> node)
00382 : InsideListExpression(InsideListExpression::NodeNot),
00383 __node(node)
00384 {
00385 ;
00386 }
00387
00394 InsideListExpressionNot(const InsideListExpressionNot& I)
00395 : InsideListExpression(I),
00396 __node(I.__node)
00397 {
00398 ;
00399 }
00400
00405 ~InsideListExpressionNot()
00406 {
00407 ;
00408 }
00409 };
00410
00411
00412 class InsideListExpressionLeaf
00413 : public InsideListExpression
00414 {
00415 private:
00416
00417 ReferenceCounting<InsideExpression> __leaf;
00418
00425 std::ostream& put(std::ostream& os) const
00426 {
00427 os << *__leaf;
00428 return os;
00429 }
00430
00431 public:
00432 ReferenceCounting<Object> objects(const Scene& S);
00433
00438 void subExecute()
00439 {
00440 (*__leaf).execute();
00441 }
00442
00449 void
00450 addReferences(InsideListExpression::ReferenceList& references)
00451 {
00452 references[(*__leaf).reference()]++;
00453 }
00454
00461 InsideListExpressionLeaf(ReferenceCounting<InsideExpression> leaf)
00462 : InsideListExpression(InsideListExpression::NodeLeaf),
00463 __leaf(leaf)
00464 {
00465 ;
00466 }
00467
00474 InsideListExpressionLeaf(const InsideListExpressionLeaf& I)
00475 : InsideListExpression(I),
00476 __leaf(I.__leaf)
00477 {
00478 ;
00479 }
00480
00485 ~InsideListExpressionLeaf()
00486 {
00487 ;
00488 }
00489 };
00490
00491 #endif // INSIDE_LIST_EXPRESSION_HPP