Update procedures
[shapes.git] / source / corepoint.cc
blobcbd1bebed46af8d9277ca2395762ea085d925641
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, 2009, 2014 Henrik Tidefelt
19 #include <cmath>
21 #include "Shapes_Helpers_decls.h"
23 #include "shapescore.h"
24 #include "ast.h"
25 #include "globals.h"
26 #include "shapesexceptions.h"
27 #include "consts.h"
28 #include "simplepdfi.h"
30 #include <iostream>
31 #include <sstream>
32 #include <fstream>
33 #include <vector>
34 #include <stdio.h>
36 using namespace Shapes;
39 namespace Shapes
41 namespace Lang
43 class Core_duration : public Lang::CoreFunction
45 public:
46 Core_duration( const RefCountPtr< const Ast::NamespacePath > & ns, const char * name ) : CoreFunction( ns, name ) { }
47 virtual void
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_ );
53 try
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( ) ) ),
59 evalState );
60 return;
62 catch( const NonLocalExit::NotThisType & ball )
64 /* Wrong type; never mind!.. but see below!
68 try
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( ) ) ),
74 evalState );
75 return;
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
89 public:
90 Core_controlling_maximizer( const RefCountPtr< const Ast::NamespacePath > & ns, const char * name ) : CoreFunction( ns, name ) { }
91 virtual void
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 >( );
100 size_t argsi = 0;
103 p = Helpers::elementaryPathTry2D( args.getValue( argsi ) );
105 catch( const NonLocalExit::NotThisType & ball )
107 goto nextType1;
110 ++argsi;
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 ),
117 evalState );
118 return;
121 nextType1:
124 typedef const Lang::ElementaryPath3D ArgType0;
125 RefCountPtr< ArgType0 > p = NullPtr< ArgType0 >( );
126 size_t argsi = 0;
129 p = Helpers::elementaryPathTry3D( args.getValue( argsi ) );
131 catch( const NonLocalExit::NotThisType & ball )
133 goto nextType2;
136 ++argsi;
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 ),
143 evalState );
144 return;
147 nextType2:
148 throw Exceptions::CoreTypeMismatch( callLoc, id_, args, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
152 class Core_discrete_mean : public Lang::CoreFunction
154 public:
155 Core_discrete_mean( const RefCountPtr< const Ast::NamespacePath > & ns, const char * name ) : CoreFunction( ns, name ) { }
156 virtual void
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_ );
162 size_t argsi = 0;
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( ),
170 evalState );
171 return;
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( ),
185 evalState );
186 return;
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
200 public:
201 Core_discrete_maximizer( const RefCountPtr< const Ast::NamespacePath > & ns, const char * name ) : CoreFunction( ns, name ) { }
202 virtual void
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 >( );
211 size_t argsi = 0;
214 p = Helpers::elementaryPathTry2D( args.getValue( argsi ) );
216 catch( const NonLocalExit::NotThisType & ball )
218 goto nextType1;
221 ++argsi;
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 ) ) ),
229 evalState );
230 return;
233 nextType1:
236 typedef const Lang::ElementaryPath3D ArgType0;
237 RefCountPtr< ArgType0 > p = NullPtr< ArgType0 >( );
238 size_t argsi = 0;
241 p = Helpers::elementaryPathTry3D( args.getValue( argsi ) );
243 catch( const NonLocalExit::NotThisType & ball )
245 goto nextType2;
248 ++argsi;
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 ) ) ),
256 evalState );
257 return;
260 nextType2:
261 throw Exceptions::CoreTypeMismatch( callLoc, id_, args, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
265 class Core_discrete_approximator : public Lang::CoreFunction
267 public:
268 Core_discrete_approximator( const RefCountPtr< const Ast::NamespacePath > & ns, const char * name ) : CoreFunction( ns, name ) { }
269 virtual void
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 >( );
278 size_t argsi = 0;
281 p = Helpers::elementaryPathTry2D( args.getValue( argsi ) );
283 catch( const NonLocalExit::NotThisType & ball )
285 goto nextType1;
288 ++argsi;
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 ) ) ),
296 evalState );
297 return;
300 nextType1:
303 typedef const Lang::ElementaryPath3D ArgType0;
304 RefCountPtr< ArgType0 > p = NullPtr< ArgType0 >( );
305 size_t argsi = 0;
308 p = Helpers::elementaryPathTry3D( args.getValue( argsi ) );
310 catch( const NonLocalExit::NotThisType & ball )
312 goto nextType2;
315 ++argsi;
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 ) ) ),
323 evalState );
324 return;
327 nextType2:
328 throw Exceptions::CoreTypeMismatch( callLoc, id_, args, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
332 class Core_continuous_mean : public Lang::CoreFunction
334 public:
335 Core_continuous_mean( const RefCountPtr< const Ast::NamespacePath > & ns, const char * name ) : CoreFunction( ns, name ) { }
336 virtual void
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_ );
342 size_t argsi = 0;
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( ),
350 evalState );
351 return;
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( ),
365 evalState );
366 return;
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
380 public:
381 Core_continuous_maximizer( const RefCountPtr< const Ast::NamespacePath > & ns, const char * name ) : CoreFunction( ns, name ) { }
382 virtual void
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 >( );
391 size_t argsi = 0;
394 p = Helpers::elementaryPathTry2D( args.getValue( argsi ) );
396 catch( const NonLocalExit::NotThisType & ball )
398 goto nextType1;
401 ++argsi;
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 ) ) ),
409 evalState );
410 return;
413 nextType1:
416 typedef const Lang::ElementaryPath3D ArgType0;
417 RefCountPtr< ArgType0 > p = NullPtr< ArgType0 >( );
418 size_t argsi = 0;
421 p = Helpers::elementaryPathTry3D( args.getValue( argsi ) );
423 catch( const NonLocalExit::NotThisType & ball )
425 goto nextType2;
428 ++argsi;
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 ) ) ),
436 evalState );
437 return;
440 nextType2:
441 throw Exceptions::CoreTypeMismatch( callLoc, id_, args, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
445 class Core_continuous_approximator : public Lang::CoreFunction
447 public:
448 Core_continuous_approximator( const RefCountPtr< const Ast::NamespacePath > & ns, const char * name ) : CoreFunction( ns, name ) { }
449 virtual void
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 >( );
458 size_t argsi = 0;
461 p = Helpers::elementaryPathTry2D( args.getValue( argsi ) );
463 catch( const NonLocalExit::NotThisType & ball )
465 goto nextType1;
468 ++argsi;
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 ) ) ),
479 evalState );
480 return;
482 catch( const NonLocalExit::NotThisType & ball )
484 goto nextType11;
488 nextType11:
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 ) ) ) ),
500 evalState );
501 return;
503 catch( const NonLocalExit::NotThisType & ball )
505 goto nextType12;
509 nextType12:
510 throw Exceptions::CoreTypeMismatch( callLoc, id_, args, 1, Helpers::typeSetString( Lang::Coords2D::staticTypeName( ), Lang::ElementaryPath2D::staticTypeName( ) ) );
513 nextType1:
516 typedef const Lang::ElementaryPath3D ArgType0;
517 RefCountPtr< ArgType0 > p = NullPtr< ArgType0 >( );
518 size_t argsi = 0;
521 p = Helpers::elementaryPathTry3D( args.getValue( argsi ) );
523 catch( const NonLocalExit::NotThisType & ball )
525 goto nextType2;
528 ++argsi;
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 ) ) ),
539 evalState );
540 return;
542 catch( const NonLocalExit::NotThisType & ball )
544 goto nextType21;
548 nextType21:
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 ) ) ) ),
560 evalState );
561 return;
563 catch( const NonLocalExit::NotThisType & ball )
565 goto nextType22;
569 nextType22:
570 throw Exceptions::CoreTypeMismatch( callLoc, id_, args, 1, Helpers::typeSetString( Lang::Coords3D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
573 nextType2:
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;
582 public:
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; } }
585 virtual void
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;
592 size_t argsi = 0;
593 RefCountPtr< ArgType1 > p = Helpers::elementaryPathCast2D( id_, args, argsi, callLoc );
595 ++argsi;
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 ) ) ) ),
607 evalState );
609 catch( const Exceptions::OutOfRange & ball )
611 if( idKey == 0 )
613 Ast::Identifier * handlerId = Lang::HANDLER_NO_INTERSECTION.newAbsolute( );
614 idKey = new Kernel::Environment::LexicalKey( Ast::theGlobalAnalysisEnvironment->findLexicalDynamicKey( callLoc, *handlerId ) );
615 delete 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 );
633 void
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" ) );