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
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, 2009, 2014 Henrik Tidefelt
21 #include "Shapes_Helpers_decls.h"
23 #include "shapescore.h"
26 #include "shapesexceptions.h"
28 #include "simplepdfi.h"
36 using namespace Shapes
;
43 class Core_duration
: public Lang::CoreFunction
46 Core_duration( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
48 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
50 const size_t ARITY
= 1;
51 CHECK_ARITY( args
, ARITY
, id_
);
55 typedef const Lang::ElementaryPath2D ArgType
;
56 RefCountPtr
< ArgType
> arg
= Helpers::elementaryPathTry2D( args
.getValue( 0 ) );
57 Kernel::ContRef cont
= evalState
->cont_
;
58 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( arg
->duration( ) ) ),
62 catch( const NonLocalExit::NotThisType
& ball
)
64 /* Wrong type; never mind!.. but see below!
70 typedef const Lang::ElementaryPath3D ArgType
;
71 RefCountPtr
< ArgType
> arg
= Helpers::elementaryPathTry3D( args
.getValue( 0 ) );
72 Kernel::ContRef cont
= evalState
->cont_
;
73 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( arg
->duration( ) ) ),
77 catch( const NonLocalExit::NotThisType
& ball
)
79 /* Wrong type; never mind!.. but see below!
83 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
87 class Core_controlling_maximizer
: public Lang::CoreFunction
90 Core_controlling_maximizer( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
92 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
94 const size_t ARITY
= 2;
95 CHECK_ARITY( args
, ARITY
, id_
);
98 typedef const Lang::ElementaryPath2D ArgType0
;
99 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
103 p
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
105 catch( const NonLocalExit::NotThisType
& ball
)
112 typedef const Lang::FloatPair ArgType1
;
113 RefCountPtr
< ArgType1
> d
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
115 Kernel::ContRef cont
= evalState
->cont_
;
116 cont
->takeValue( p
->controllingMaximizer( *d
),
124 typedef const Lang::ElementaryPath3D ArgType0
;
125 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
129 p
= Helpers::elementaryPathTry3D( args
.getValue( argsi
) );
131 catch( const NonLocalExit::NotThisType
& ball
)
138 typedef const Lang::FloatTriple ArgType1
;
139 RefCountPtr
< ArgType1
> d
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
141 Kernel::ContRef cont
= evalState
->cont_
;
142 cont
->takeValue( p
->controllingMaximizer( *d
),
148 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
152 class Core_discrete_mean
: public Lang::CoreFunction
155 Core_discrete_mean( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
157 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
159 const size_t ARITY
= 1;
160 CHECK_ARITY( args
, ARITY
, id_
);
166 typedef const Lang::ElementaryPath2D ArgType
;
167 RefCountPtr
< ArgType
> p
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
168 Kernel::ContRef cont
= evalState
->cont_
;
169 cont
->takeValue( p
->discreteMean( ),
173 catch( const NonLocalExit::NotThisType
& ball
)
175 /* Wrong type; never mind!.. but see below!
181 typedef const Lang::ElementaryPath3D ArgType
;
182 RefCountPtr
< ArgType
> p
= Helpers::elementaryPathTry3D( args
.getValue( argsi
) );
183 Kernel::ContRef cont
= evalState
->cont_
;
184 cont
->takeValue( p
->discreteMean( ),
188 catch( const NonLocalExit::NotThisType
& ball
)
190 /* Wrong type; never mind!.. but see below!
194 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
198 class Core_discrete_maximizer
: public Lang::CoreFunction
201 Core_discrete_maximizer( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
203 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
205 const size_t ARITY
= 2;
206 CHECK_ARITY( args
, ARITY
, id_
);
209 typedef const Lang::ElementaryPath2D ArgType0
;
210 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
214 p
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
216 catch( const NonLocalExit::NotThisType
& ball
)
223 typedef const Lang::FloatPair ArgType1
;
224 RefCountPtr
< ArgType1
> d
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
226 Kernel::ContRef cont
= evalState
->cont_
;
227 typedef const Lang::PathSlider2D ResultType
;
228 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, p
->discreteMaximizer( *d
) ) ),
236 typedef const Lang::ElementaryPath3D ArgType0
;
237 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
241 p
= Helpers::elementaryPathTry3D( args
.getValue( argsi
) );
243 catch( const NonLocalExit::NotThisType
& ball
)
250 typedef const Lang::FloatTriple ArgType1
;
251 RefCountPtr
< ArgType1
> d
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
253 Kernel::ContRef cont
= evalState
->cont_
;
254 typedef const Lang::PathSlider3D ResultType
;
255 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, p
->discreteMaximizer( *d
) ) ),
261 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
265 class Core_discrete_approximator
: public Lang::CoreFunction
268 Core_discrete_approximator( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
270 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
272 const size_t ARITY
= 2;
273 CHECK_ARITY( args
, ARITY
, id_
);
276 typedef const Lang::ElementaryPath2D ArgType0
;
277 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
281 p
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
283 catch( const NonLocalExit::NotThisType
& ball
)
290 typedef const Lang::Coords2D ArgType1
;
291 RefCountPtr
< ArgType1
> d
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
293 Kernel::ContRef cont
= evalState
->cont_
;
294 typedef const Lang::PathSlider2D ResultType
;
295 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, p
->discreteApproximator( *d
) ) ),
303 typedef const Lang::ElementaryPath3D ArgType0
;
304 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
308 p
= Helpers::elementaryPathTry3D( args
.getValue( argsi
) );
310 catch( const NonLocalExit::NotThisType
& ball
)
317 typedef const Lang::Coords3D ArgType1
;
318 RefCountPtr
< ArgType1
> d
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
320 Kernel::ContRef cont
= evalState
->cont_
;
321 typedef const Lang::PathSlider3D ResultType
;
322 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, p
->discreteApproximator( *d
) ) ),
328 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
332 class Core_continuous_mean
: public Lang::CoreFunction
335 Core_continuous_mean( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
337 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
339 const size_t ARITY
= 1;
340 CHECK_ARITY( args
, ARITY
, id_
);
346 typedef const Lang::ElementaryPath2D ArgType
;
347 RefCountPtr
< ArgType
> p
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
348 Kernel::ContRef cont
= evalState
->cont_
;
349 cont
->takeValue( p
->continuousMean( ),
353 catch( const NonLocalExit::NotThisType
& ball
)
355 /* Wrong type; never mind!.. but see below!
361 typedef const Lang::ElementaryPath3D ArgType
;
362 RefCountPtr
< ArgType
> p
= Helpers::elementaryPathTry3D( args
.getValue( argsi
) );
363 Kernel::ContRef cont
= evalState
->cont_
;
364 cont
->takeValue( p
->continuousMean( ),
368 catch( const NonLocalExit::NotThisType
& ball
)
370 /* Wrong type; never mind!.. but see below!
374 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
378 class Core_continuous_maximizer
: public Lang::CoreFunction
381 Core_continuous_maximizer( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
383 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
385 const size_t ARITY
= 2;
386 CHECK_ARITY( args
, ARITY
, id_
);
389 typedef const Lang::ElementaryPath2D ArgType0
;
390 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
394 p
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
396 catch( const NonLocalExit::NotThisType
& ball
)
403 typedef const Lang::FloatPair ArgType1
;
404 RefCountPtr
< ArgType1
> d
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
406 Kernel::ContRef cont
= evalState
->cont_
;
407 typedef const Lang::PathSlider2D ResultType
;
408 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, p
->continuousMaximizer( *d
) ) ),
416 typedef const Lang::ElementaryPath3D ArgType0
;
417 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
421 p
= Helpers::elementaryPathTry3D( args
.getValue( argsi
) );
423 catch( const NonLocalExit::NotThisType
& ball
)
430 typedef const Lang::FloatTriple ArgType1
;
431 RefCountPtr
< ArgType1
> d
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
433 Kernel::ContRef cont
= evalState
->cont_
;
434 typedef const Lang::PathSlider3D ResultType
;
435 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, p
->continuousMaximizer( *d
) ) ),
441 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
445 class Core_continuous_approximator
: public Lang::CoreFunction
448 Core_continuous_approximator( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
450 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
452 const size_t ARITY
= 2;
453 CHECK_ARITY( args
, ARITY
, id_
);
456 typedef const Lang::ElementaryPath2D ArgType0
;
457 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
461 p
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
463 catch( const NonLocalExit::NotThisType
& ball
)
471 typedef const Lang::Coords2D ArgType1
;
474 RefCountPtr
< ArgType1
> d
= Helpers::try_cast_CoreArgument
< ArgType1
>( args
.getValue( argsi
) );
476 Kernel::ContRef cont
= evalState
->cont_
;
477 typedef const Lang::PathSlider2D ResultType
;
478 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, p
->continuousApproximator( *d
) ) ),
482 catch( const NonLocalExit::NotThisType
& ball
)
490 typedef const Lang::ElementaryPath2D ArgType1
;
491 RefCountPtr
< ArgType1
> p2
= NullPtr
< ArgType1
>( );
494 p2
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
495 RefCountPtr
< const Lang::Structure
> info
= NullPtr
< typeof *info
>( );
496 Concrete::SplineTime t
= p
->continuousApproximator( p2
, & info
);
497 Kernel::ContRef cont
= evalState
->cont_
;
498 typedef const Lang::PathSlider2D ResultType
;
499 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, t
, Kernel::VariableHandle( new Kernel::Variable( info
) ) ) ),
503 catch( const NonLocalExit::NotThisType
& ball
)
510 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 1, Helpers::typeSetString( Lang::Coords2D::staticTypeName( ), Lang::ElementaryPath2D::staticTypeName( ) ) );
516 typedef const Lang::ElementaryPath3D ArgType0
;
517 RefCountPtr
< ArgType0
> p
= NullPtr
< ArgType0
>( );
521 p
= Helpers::elementaryPathTry3D( args
.getValue( argsi
) );
523 catch( const NonLocalExit::NotThisType
& ball
)
531 typedef const Lang::Coords3D ArgType1
;
534 RefCountPtr
< ArgType1
> d
= Helpers::try_cast_CoreArgument
< ArgType1
>( args
.getValue( argsi
) );
536 Kernel::ContRef cont
= evalState
->cont_
;
537 typedef const Lang::PathSlider3D ResultType
;
538 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, p
->continuousApproximator( *d
) ) ),
542 catch( const NonLocalExit::NotThisType
& ball
)
550 typedef const Lang::ElementaryPath3D ArgType1
;
551 RefCountPtr
< ArgType1
> p2
= NullPtr
< ArgType1
>( );
554 p2
= Helpers::elementaryPathTry3D( args
.getValue( argsi
) );
555 RefCountPtr
< const Lang::Structure
> info
= NullPtr
< typeof *info
>( );
556 Concrete::SplineTime t
= p
->continuousApproximator( p2
, & info
);
557 Kernel::ContRef cont
= evalState
->cont_
;
558 typedef const Lang::PathSlider3D ResultType
;
559 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, t
, Kernel::VariableHandle( new Kernel::Variable( info
) ) ) ),
563 catch( const NonLocalExit::NotThisType
& ball
)
570 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 1, Helpers::typeSetString( Lang::Coords3D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
574 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
579 class Core_intersection
: public Lang::CoreFunction
581 mutable Kernel::Environment::LexicalKey
* idKey
;
583 Core_intersection( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
), idKey( 0 ) { }
584 virtual ~Core_intersection( ) { if( idKey
!= 0 ){ delete idKey
; } }
586 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
588 const size_t ARITY
= 2;
589 CHECK_ARITY( args
, ARITY
, id_
);
591 typedef const Lang::ElementaryPath2D ArgType1
;
593 RefCountPtr
< ArgType1
> p
= Helpers::elementaryPathCast2D( id_
, args
, argsi
, callLoc
);
597 typedef const Lang::ElementaryPath2D ArgType2
;
598 RefCountPtr
< ArgType2
> p2
= Helpers::elementaryPathCast2D( id_
, args
, argsi
, callLoc
);
600 Kernel::ContRef cont
= evalState
->cont_
;
603 RefCountPtr
< const Lang::Structure
> info
= NullPtr
< typeof *info
>( );
604 Concrete::SplineTime t
= p
->intersection( p2
, & info
);
605 typedef const Lang::PathSlider2D ResultType
;
606 cont
->takeValue( RefCountPtr
< ResultType
>( new ResultType( p
, t
, Kernel::VariableHandle( new Kernel::Variable( info
) ) ) ),
609 catch( const Exceptions::OutOfRange
& ball
)
613 Ast::Identifier
* handlerId
= Lang::HANDLER_NO_INTERSECTION
.newAbsolute( );
614 idKey
= new Kernel::Environment::LexicalKey( Ast::theGlobalAnalysisEnvironment
->findLexicalDynamicKey( callLoc
, *handlerId
) );
618 const Kernel::DynamicVariableProperties
& dynProps
= Kernel::theGlobalEnvironment
->lookupDynamicVariable( *idKey
);
620 Kernel::VariableHandle handler
= dynProps
.fetch( evalState
->dyn_
);
622 typedef const Lang::Function HandlerType
;
624 RefCountPtr
< HandlerType
> fun( handler
->getVal
< HandlerType
>( callLoc
) );
625 fun
->call( evalState
, args
.getValue( 0 ), args
.getValue( 1 ), callLoc
);
634 Kernel::registerCore_point( Kernel::Environment
* env
)
636 env
->initDefineCoreFunction( new Lang::Core_duration( Lang::THE_NAMESPACE_Shapes_Geometry
, "duration" ) );
637 env
->initDefineCoreFunction( new Lang::Core_controlling_maximizer( Lang::THE_NAMESPACE_Shapes_Geometry
, "controlling_maximizer" ) );
638 env
->initDefineCoreFunction( new Lang::Core_discrete_mean( Lang::THE_NAMESPACE_Shapes_Geometry
, "pathpoint_mean" ) );
639 env
->initDefineCoreFunction( new Lang::Core_discrete_maximizer( Lang::THE_NAMESPACE_Shapes_Geometry
, "pathpoint_maximizer" ) );
640 env
->initDefineCoreFunction( new Lang::Core_discrete_approximator( Lang::THE_NAMESPACE_Shapes_Geometry
, "pathpoint_approximator" ) );
641 env
->initDefineCoreFunction( new Lang::Core_continuous_mean( Lang::THE_NAMESPACE_Shapes_Geometry
, "mean" ) );
642 env
->initDefineCoreFunction( new Lang::Core_continuous_maximizer( Lang::THE_NAMESPACE_Shapes_Geometry
, "maximizer" ) );
643 env
->initDefineCoreFunction( new Lang::Core_continuous_approximator( Lang::THE_NAMESPACE_Shapes_Geometry
, "approximator" ) );
644 env
->initDefineCoreFunction( new Lang::Core_intersection( Lang::THE_NAMESPACE_Shapes_Geometry
, "intersection" ) );