Merge branch 'gh/maint-clean' into ht/-include
[shapes.git] / source / facettypes.cc
blob21f42366852aa89eeb16384f12dfffda79d6179e
1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * any later version.
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008 Henrik Tidefelt
19 #include "facettypes.h"
20 #include "dynamicenvironment.h"
21 #include "lighttypes.h"
22 #include "ast.h"
23 #include "astvar.h"
24 #include "isnan.h"
25 #include "globals.h"
27 using namespace Shapes;
30 Lang::ReflectionsBinding::ReflectionsBinding( const char * id, const Ast::DynamicBindingExpression * bindingExpr, const RefCountPtr< const Lang::SpecularReflection > & reflections )
31 : bindingExpr_( bindingExpr ), reflections_( reflections ), id_( id )
32 { }
34 Lang::ReflectionsBinding::~ReflectionsBinding( )
35 { }
37 void
38 Lang::ReflectionsBinding::bind( MapType & bindings, Kernel::SystemDynamicVariables ** sysBindings ) const
40 if( *sysBindings == 0 )
42 *sysBindings = new Kernel::SystemDynamicVariables( );
43 Kernel::FacetState * newState = new Kernel::FacetState( );
44 newState->reflections_ = reflections_;
45 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
46 return;
49 if( (*sysBindings)->facetState_ == NullPtr< const Kernel::FacetState >( ) )
51 Kernel::FacetState * newState = new Kernel::FacetState( );
52 newState->reflections_ = reflections_;
53 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
54 return;
57 Kernel::FacetState * newState = new Kernel::FacetState( *((*sysBindings)->facetState_) );
59 if( newState->reflections_ != NullPtr< const Lang::SpecularReflection >( ) )
61 throw Exceptions::MultipleDynamicBind( id_, bindingExpr_->idLoc( ), Ast::THE_UNKNOWN_LOCATION );
64 newState->reflections_ = reflections_;
65 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
68 void
69 Lang::ReflectionsBinding::show( std::ostream & os ) const
71 os << Interaction::DYNAMIC_VARIABLE_PREFIX << id_ << ":" ;
72 reflections_->show( os );
75 void
76 Lang::ReflectionsBinding::gcMark( Kernel::GCMarkedSet & marked )
78 const_cast< Lang::SpecularReflection * >( reflections_.getPtr( ) )->gcMark( marked );
83 Lang::AutoIntensityBinding::AutoIntensityBinding( const char * id, const Ast::DynamicBindingExpression * bindingExpr, const RefCountPtr< const Lang::Color > & color )
84 : bindingExpr_( bindingExpr ), color_( color ), id_( id )
85 { }
87 Lang::AutoIntensityBinding::~AutoIntensityBinding( )
88 { }
90 void
91 Lang::AutoIntensityBinding::bind( MapType & bindings, Kernel::SystemDynamicVariables ** sysBindings ) const
93 if( *sysBindings == 0 )
95 *sysBindings = new Kernel::SystemDynamicVariables( );
96 Kernel::FacetState * newState = new Kernel::FacetState( );
97 newState->autoIntensity_ = color_;
98 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
99 return;
102 if( (*sysBindings)->facetState_ == NullPtr< const Kernel::FacetState >( ) )
104 Kernel::FacetState * newState = new Kernel::FacetState( );
105 newState->autoIntensity_ = color_;
106 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
107 return;
110 Kernel::FacetState * newState = new Kernel::FacetState( *((*sysBindings)->facetState_) );
112 if( newState->autoIntensity_ != NullPtr< const Lang::Color >( ) )
114 throw Exceptions::MultipleDynamicBind( id_, bindingExpr_->idLoc( ), Ast::THE_UNKNOWN_LOCATION );
117 newState->autoIntensity_ = color_;
118 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
121 void
122 Lang::AutoIntensityBinding::show( std::ostream & os ) const
124 os << Interaction::DYNAMIC_VARIABLE_PREFIX << id_ << ":" ;
125 color_->show( os );
128 void
129 Lang::AutoIntensityBinding::gcMark( Kernel::GCMarkedSet & marked )
131 const_cast< Lang::Color * >( color_.getPtr( ) )->gcMark( marked );
136 Lang::AutoScatteringBinding::AutoScatteringBinding( const char * id, const Ast::DynamicBindingExpression * bindingExpr, const RefCountPtr< const Lang::SpecularReflection > & reflections )
137 : bindingExpr_( bindingExpr ), reflections_( reflections ), id_( id )
140 Lang::AutoScatteringBinding::~AutoScatteringBinding( )
143 void
144 Lang::AutoScatteringBinding::bind( MapType & bindings, Kernel::SystemDynamicVariables ** sysBindings ) const
146 if( *sysBindings == 0 )
148 *sysBindings = new Kernel::SystemDynamicVariables( );
149 Kernel::FacetState * newState = new Kernel::FacetState( );
150 newState->autoScattering_ = reflections_;
151 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
152 return;
155 if( (*sysBindings)->facetState_ == NullPtr< const Kernel::FacetState >( ) )
157 Kernel::FacetState * newState = new Kernel::FacetState( );
158 newState->autoScattering_ = reflections_;
159 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
160 return;
163 Kernel::FacetState * newState = new Kernel::FacetState( *((*sysBindings)->facetState_) );
165 if( newState->autoScattering_ != NullPtr< const Lang::SpecularReflection >( ) )
167 throw Exceptions::MultipleDynamicBind( id_, bindingExpr_->idLoc( ), Ast::THE_UNKNOWN_LOCATION );
170 newState->autoScattering_ = reflections_;
171 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
174 void
175 Lang::AutoScatteringBinding::show( std::ostream & os ) const
177 os << Interaction::DYNAMIC_VARIABLE_PREFIX << id_ << ":" ;
178 reflections_->show( os );
181 void
182 Lang::AutoScatteringBinding::gcMark( Kernel::GCMarkedSet & marked )
184 const_cast< Lang::SpecularReflection * >( reflections_.getPtr( ) )->gcMark( marked );
188 Lang::ViewResolutionBinding::ViewResolutionBinding( const char * id, const Ast::DynamicBindingExpression * bindingExpr, const Concrete::Length resolution )
189 : bindingExpr_( bindingExpr ), resolution_( resolution ), id_( id )
192 Lang::ViewResolutionBinding::~ViewResolutionBinding( )
195 void
196 Lang::ViewResolutionBinding::bind( MapType & bindings, Kernel::SystemDynamicVariables ** sysBindings ) const
198 if( *sysBindings == 0 )
200 *sysBindings = new Kernel::SystemDynamicVariables( );
201 Kernel::FacetState * newState = new Kernel::FacetState( );
202 newState->viewResolution_ = resolution_;
203 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
204 return;
207 if( (*sysBindings)->facetState_ == NullPtr< const Kernel::FacetState >( ) )
209 Kernel::FacetState * newState = new Kernel::FacetState( );
210 newState->viewResolution_ = resolution_;
211 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
212 return;
215 Kernel::FacetState * newState = new Kernel::FacetState( *((*sysBindings)->facetState_) );
217 if( ! IS_NAN( newState->viewResolution_ ) )
219 throw Exceptions::MultipleDynamicBind( id_, bindingExpr_->idLoc( ), Ast::THE_UNKNOWN_LOCATION );
222 newState->viewResolution_ = resolution_;
223 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
226 void
227 Lang::ViewResolutionBinding::show( std::ostream & os ) const
229 os << Interaction::DYNAMIC_VARIABLE_PREFIX << id_ << ":"
230 << resolution_ / Interaction::displayUnit << Interaction::displayUnitName ;
233 void
234 Lang::ViewResolutionBinding::gcMark( Kernel::GCMarkedSet & marked )
238 Lang::ShadeOrderBinding::ShadeOrderBinding( const char * id, const Ast::DynamicBindingExpression * bindingExpr, const Computation::FacetShadeOrder order )
239 : bindingExpr_( bindingExpr ), order_( order ), id_( id )
242 Lang::ShadeOrderBinding::~ShadeOrderBinding( )
245 void
246 Lang::ShadeOrderBinding::bind( MapType & bindings, Kernel::SystemDynamicVariables ** sysBindings ) const
248 if( *sysBindings == 0 )
250 *sysBindings = new Kernel::SystemDynamicVariables( );
251 Kernel::FacetState * newState = new Kernel::FacetState( );
252 newState->shadeOrder_ = order_;
253 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
254 return;
257 if( (*sysBindings)->facetState_ == NullPtr< const Kernel::FacetState >( ) )
259 Kernel::FacetState * newState = new Kernel::FacetState( );
260 newState->shadeOrder_ = order_;
261 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
262 return;
265 Kernel::FacetState * newState = new Kernel::FacetState( *((*sysBindings)->facetState_) );
267 if( newState->shadeOrder_ != -1 )
269 throw Exceptions::MultipleDynamicBind( id_, bindingExpr_->idLoc( ), Ast::THE_UNKNOWN_LOCATION );
272 newState->shadeOrder_ = order_;
273 (*sysBindings)->facetState_ = RefCountPtr< const Kernel::FacetState >( newState );
276 void
277 Lang::ShadeOrderBinding::show( std::ostream & os ) const
279 os << Interaction::DYNAMIC_VARIABLE_PREFIX << id_ << ":"
280 << "'" << order_ ;
283 void
284 Lang::ShadeOrderBinding::gcMark( Kernel::GCMarkedSet & marked )
289 Kernel::ReflectionsDynamicVariableProperties::ReflectionsDynamicVariableProperties( const char * name )
290 : Kernel::DynamicVariableProperties( name )
293 Kernel::ReflectionsDynamicVariableProperties::~ReflectionsDynamicVariableProperties( )
296 Kernel::VariableHandle
297 Kernel::ReflectionsDynamicVariableProperties::fetch( const Kernel::PassedDyn & dyn ) const
299 RefCountPtr< const Kernel::FacetState > facetState = dyn->getFacetState( );
300 return Kernel::VariableHandle( new Kernel::Variable( facetState->reflections_ ) );
303 void
304 Kernel::ReflectionsDynamicVariableProperties::makeBinding( Kernel::VariableHandle val, const Ast::DynamicBindingExpression * bindingExpr, Kernel::EvalState * evalState ) const
306 RefCountPtr< const Lang::SpecularReflection > reflection = val->getVal< const Lang::SpecularReflection >( bindingExpr->exprLoc( ) );
307 Kernel::ContRef cont = evalState->cont_;
308 cont->takeValue( Kernel::ValueRef( new Lang::ReflectionsBinding( name_, bindingExpr, reflection ) ),
309 evalState );
313 Kernel::AutoIntensityDynamicVariableProperties::AutoIntensityDynamicVariableProperties( const char * name )
314 : Kernel::DynamicVariableProperties( name )
317 Kernel::AutoIntensityDynamicVariableProperties::~AutoIntensityDynamicVariableProperties( )
320 Kernel::VariableHandle
321 Kernel::AutoIntensityDynamicVariableProperties::fetch( const Kernel::PassedDyn & dyn ) const
323 RefCountPtr< const Kernel::FacetState > facetState = dyn->getFacetState( );
324 return Kernel::VariableHandle( new Kernel::Variable( facetState->autoIntensity_ ) );
327 void
328 Kernel::AutoIntensityDynamicVariableProperties::makeBinding( Kernel::VariableHandle val, const Ast::DynamicBindingExpression * bindingExpr, Kernel::EvalState * evalState ) const
330 RefCountPtr< const Lang::Color > color = val->getVal< const Lang::Color >( bindingExpr->exprLoc( ) );
331 Kernel::ContRef cont = evalState->cont_;
332 cont->takeValue( Kernel::ValueRef( new Lang::AutoIntensityBinding( name_, bindingExpr, color ) ),
333 evalState );
337 Kernel::AutoScatteringDynamicVariableProperties::AutoScatteringDynamicVariableProperties( const char * name )
338 : Kernel::DynamicVariableProperties( name )
341 Kernel::AutoScatteringDynamicVariableProperties::~AutoScatteringDynamicVariableProperties( )
344 Kernel::VariableHandle
345 Kernel::AutoScatteringDynamicVariableProperties::fetch( const Kernel::PassedDyn & dyn ) const
347 RefCountPtr< const Kernel::FacetState > facetState = dyn->getFacetState( );
348 return Kernel::VariableHandle( new Kernel::Variable( facetState->autoScattering_ ) );
351 void
352 Kernel::AutoScatteringDynamicVariableProperties::makeBinding( Kernel::VariableHandle val, const Ast::DynamicBindingExpression * bindingExpr, Kernel::EvalState * evalState ) const
354 RefCountPtr< const Lang::SpecularReflection > reflection = val->getVal< const Lang::SpecularReflection >( bindingExpr->exprLoc( ) );
355 Kernel::ContRef cont = evalState->cont_;
356 cont->takeValue( Kernel::ValueRef( new Lang::AutoScatteringBinding( name_, bindingExpr, reflection ) ),
357 evalState );
361 Kernel::ViewResolutionDynamicVariableProperties::ViewResolutionDynamicVariableProperties( const char * name )
362 : Kernel::DynamicVariableProperties( name )
365 Kernel::ViewResolutionDynamicVariableProperties::~ViewResolutionDynamicVariableProperties( )
368 Kernel::VariableHandle
369 Kernel::ViewResolutionDynamicVariableProperties::fetch( const Kernel::PassedDyn & dyn ) const
371 RefCountPtr< const Kernel::FacetState > facetState = dyn->getFacetState( );
372 return Helpers::newValHandle( new Lang::Length( facetState->viewResolution_ ) );
375 void
376 Kernel::ViewResolutionDynamicVariableProperties::makeBinding( Kernel::VariableHandle val, const Ast::DynamicBindingExpression * bindingExpr, Kernel::EvalState * evalState ) const
378 RefCountPtr< const Lang::Length > res = val->getVal< const Lang::Length >( bindingExpr->exprLoc( ) );
379 if( res->get( ) <= 0 )
381 throw Exceptions::OutOfRange( bindingExpr->exprLoc( ), strrefdup( "The length must be non-negative." ) );
383 Kernel::ContRef cont = evalState->cont_;
384 cont->takeValue( Kernel::ValueRef( new Lang::ViewResolutionBinding( name_, bindingExpr, res->get( ) ) ),
385 evalState );
388 Kernel::ShadeOrderDynamicVariableProperties::ShadeOrderDynamicVariableProperties( const char * name )
389 : Kernel::DynamicVariableProperties( name )
392 Kernel::ShadeOrderDynamicVariableProperties::~ShadeOrderDynamicVariableProperties( )
395 Kernel::VariableHandle
396 Kernel::ShadeOrderDynamicVariableProperties::fetch( const Kernel::PassedDyn & dyn ) const
398 RefCountPtr< const Kernel::FacetState > facetState = dyn->getFacetState( );
399 return Helpers::newValHandle( new Lang::Integer( facetState->shadeOrder_ ) );
402 void
403 Kernel::ShadeOrderDynamicVariableProperties::makeBinding( Kernel::VariableHandle val, const Ast::DynamicBindingExpression * bindingExpr, Kernel::EvalState * evalState ) const
405 RefCountPtr< const Lang::Integer > order = val->getVal< const Lang::Integer >( bindingExpr->exprLoc( ) );
406 if( order->val_ < 0 || order->val_ > 2 )
408 throw Exceptions::OutOfRange( bindingExpr->exprLoc( ), strrefdup( "The shade order integer must be one of { 0, 1, 2 }." ) );
410 Kernel::ContRef cont = evalState->cont_;
411 cont->takeValue( Kernel::ValueRef( new Lang::ShadeOrderBinding( name_, bindingExpr, order->val_ ) ),
412 evalState );
417 Kernel::FacetState::FacetState( )
418 : reflections_( NullPtr< const Lang::SpecularReflection >( ) ),
419 autoIntensity_( NullPtr< const Lang::Color >( ) ),
420 autoScattering_( NullPtr< const Lang::SpecularReflection >( ) ),
421 viewResolution_( std::numeric_limits< double >::signaling_NaN( ) ),
422 shadeOrder_( -1 )
425 Kernel::FacetState::FacetState( const Kernel::FacetState & orig )
426 : reflections_( orig.reflections_ ),
427 autoIntensity_( orig.autoIntensity_ ),
428 autoScattering_( orig.autoScattering_ ),
429 viewResolution_( orig.viewResolution_ ),
430 shadeOrder_( orig.shadeOrder_ )
433 Kernel::FacetState::FacetState( const Kernel::FacetState & newValues, const Kernel::FacetState & oldValues )
434 : reflections_( oldValues.reflections_ ),
435 autoIntensity_( oldValues.autoIntensity_ ),
436 autoScattering_( oldValues.autoScattering_ ),
437 viewResolution_( oldValues.viewResolution_ ),
438 shadeOrder_( oldValues.shadeOrder_ )
440 if( newValues.reflections_ != NullPtr< const Lang::SpecularReflection >( ) )
442 reflections_ = newValues.reflections_;
444 if( newValues.autoIntensity_ != NullPtr< const Lang::Color >( ) )
446 autoIntensity_ = newValues.autoIntensity_;
448 if( newValues.autoScattering_ != NullPtr< const Lang::SpecularReflection >( ) )
450 autoScattering_ = newValues.autoScattering_;
452 if( ! IS_NAN( newValues.viewResolution_ ) )
454 viewResolution_ = newValues.viewResolution_;
456 if( newValues.shadeOrder_ != -1 )
458 shadeOrder_ = newValues.shadeOrder_;
462 Kernel::FacetState::FacetState( bool setDefaults )
463 : reflections_( RefCountPtr< const Lang::SpecularReflection >( new Lang::SpecularReflectionNull( ) ) ),
464 autoIntensity_( RefCountPtr< const Lang::Color >( new Lang::Gray( 0 ) ) ),
465 autoScattering_( RefCountPtr< const Lang::SpecularReflection >( new Lang::SpecularReflectionNull( ) ) ),
466 viewResolution_( Concrete::HUGE_LENGTH ),
467 shadeOrder_( 0 )
469 if( ! setDefaults )
471 throw Exceptions::InternalError( strrefdup( "setDefaults must be true in FacetState::FacetState." ) );
475 Kernel::FacetState::~FacetState( )
478 void
479 Kernel::FacetState::print( std::ostream & os, const std::string & indentation ) const
481 if( autoIntensity_ != NullPtr< const Lang::Color >( ) )
483 os << indentation << Interaction::DYNAMIC_VARIABLE_PREFIX << Lang::DYNAMIC_VARIABLE_ID_AUTOINTENSITY << ": " ;
484 autoIntensity_->show( os );
485 os << std::endl ;
487 os << "(and a bunch of other variables...)" << std::endl ;