3 #include "Shapes_Helpers_decls.h"
5 #include "shapescore.h"
7 #include "shapesexceptions.h"
9 #include "simplepdfi.h"
10 #include "autoonoff.h"
20 using namespace Shapes
;
27 RefCountPtr
< const Lang::TransparencyGroup
>
28 newSolidTransparencyGroup( const RefCountPtr
< const Lang::Drawable2D
> & obj2
, const RefCountPtr
< const Lang::Drawable2D
> & obj1
);
29 RefCountPtr
< const Lang::TransparencyGroup
>
30 newSolidTransparencyGroup( const RefCountPtr
< const Lang::Drawable2D
> & obj3
, const RefCountPtr
< const Lang::Drawable2D
> & obj2
, const RefCountPtr
< const Lang::Drawable2D
> & obj1
);
32 void stroke_helper_2D( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
, Kernel::Arguments
& args
, bool fill
, const Ast::SourceLocation
& callLoc
);
33 void stroke_helper_3D( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
, Kernel::Arguments
& args
, bool fill
, const Ast::SourceLocation
& callLoc
);
42 class Core_spot
: public Lang::CoreFunction
45 Core_spot( const char * title
) : CoreFunction( title
) { }
47 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
49 const size_t ARITY
= 1;
50 CHECK_ARITY( args
, ARITY
, title_
);
52 typedef const Lang::Coords2D ArgType
;
53 RefCountPtr
< ArgType
> p
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
);
55 ElementaryPath2D
* pth
= new ElementaryPath2D
;
56 pth
->push_back( new Concrete::PathPoint2D( p
->x_
.get( ), p
->y_
.get( ) ) );
57 if( Kernel::allowSingletonPaths
)
63 pth
->push_back( new Concrete::PathPoint2D( p
->x_
.get( ), p
->y_
.get( ) ) );
66 Kernel::GraphicsState
* capState( new Kernel::GraphicsState( *evalState
->dyn_
->getGraphicsState( ) ) );
67 capState
->cap_
= Lang::CapStyle::CAP_ROUND
;
69 Kernel::ContRef cont
= evalState
->cont_
;
70 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D
71 ( RefCountPtr
< const Kernel::GraphicsState
>( capState
),
72 RefCountPtr
< const Lang::ElementaryPath2D
>( pth
),
78 class Core_stroke
: public Lang::CoreFunction
82 Core_stroke( const char * title
, bool fill
)
83 : CoreFunction( title
, new Kernel::EvaluatedFormals( title
, true ) ), fill_( fill
)
85 formals_
->appendEvaluatedCoreFormal( "path", Kernel::THE_SLOT_VARIABLE
);
86 formals_
->appendEvaluatedCoreFormal( "head", Kernel::VariableHandle( new Kernel::Variable( Lang::THE_NO_ARROW
) ) );
87 formals_
->appendEvaluatedCoreFormal( "tail", Kernel::VariableHandle( new Kernel::Variable( Lang::THE_NO_ARROW
) ) );
91 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
93 args
.applyDefaults( );
97 typedef const Lang::ElementaryPath2D ArgType
;
98 RefCountPtr
< ArgType
> arg
= Helpers::elementaryPathTry2D( args
.getValue( 0 ) );
99 Helpers::stroke_helper_2D( evalState
, arg
, args
, fill_
, callLoc
);
102 catch( const NonLocalExit::NotThisType
& ball
)
104 /* Wrong type; never mind!.. but see below!
110 typedef const Lang::ElementaryPath3D ArgType
;
111 RefCountPtr
< ArgType
> arg
= Helpers::elementaryPathTry3D( args
.getValue( 0 ) );
112 Helpers::stroke_helper_3D( evalState
, arg
, args
, fill_
, callLoc
);
115 catch( const NonLocalExit::NotThisType
& ball
)
117 /* Wrong type; never mind!.. but see below!
121 const char * paintCmd
= fill_
? "B" : "S";
125 typedef const Lang::MultiPath2D ArgType
;
126 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
127 RefCountPtr
< const Lang::Function
> arrowHead
= Helpers::down_cast_CoreArgument
< const Lang::Function
>( title_
, args
, 1, callLoc
);
128 RefCountPtr
< const Lang::Function
> arrowTail
= Helpers::down_cast_CoreArgument
< const Lang::Function
>( title_
, args
, 2, callLoc
);
129 if( arrowHead
!= Lang::THE_NO_ARROW
||
130 arrowTail
!= Lang::THE_NO_ARROW
)
132 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrowheads/tails are not supported for composite paths." ) );
134 Kernel::ContRef cont
= evalState
->cont_
;
135 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, paintCmd
) ),
139 catch( const NonLocalExit::NotThisType
& ball
)
141 /* Wrong type; never mind!.. but see below!
147 typedef const Lang::MultiPath3D ArgType
;
148 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
149 RefCountPtr
< const Lang::Function
> arrowHead
= Helpers::down_cast_CoreArgument
< const Lang::Function
>( title_
, args
, 1, callLoc
);
150 RefCountPtr
< const Lang::Function
> arrowTail
= Helpers::down_cast_CoreArgument
< const Lang::Function
>( title_
, args
, 2, callLoc
);
151 if( arrowHead
!= Lang::THE_NO_ARROW
||
152 arrowTail
!= Lang::THE_NO_ARROW
)
154 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrowheads/tails are not supported for composite paths." ) );
156 Kernel::ContRef cont
= evalState
->cont_
;
157 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath3D( evalState
->dyn_
->getGraphicsState( ), path
, paintCmd
) ),
161 catch( const NonLocalExit::NotThisType
& ball
)
163 /* Wrong type; never mind!.. but see below!
167 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
171 class Core_fill
: public Lang::CoreFunction
174 Core_fill( const char * title
)
175 : CoreFunction( title
, new Kernel::EvaluatedFormals( title
, true ) )
177 formals_
->appendEvaluatedCoreFormal( "path", Kernel::THE_SLOT_VARIABLE
);
178 formals_
->appendEvaluatedCoreFormal( "tiebreaker", Kernel::THE_VOID_VARIABLE
);
182 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
184 args
.applyDefaults( );
186 RefCountPtr
< const Lang::Length
> tiebreaker
= Helpers::down_cast_CoreArgument
< const Lang::Length
>( title_
, args
, 1, callLoc
, true );
190 typedef const Lang::ElementaryPath2D ArgType
;
191 RefCountPtr
< ArgType
> path
= Helpers::elementaryPathTry2D( args
.getValue( 0 ) );
192 if( tiebreaker
!= NullPtr
< const Lang::Length
>( ) )
194 throw Exceptions::CoreOutOfRange( title_
, args
, 1, "The tiebreaker may not specified for 2D paths." );
196 Kernel::ContRef cont
= evalState
->cont_
;
197 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, "f" ) ),
201 catch( const NonLocalExit::NotThisType
& ball
)
203 /* Wrong type; never mind!.. but see below!
209 typedef const Lang::ElementaryPath3D ArgType
;
210 RefCountPtr
< ArgType
> path
= Helpers::elementaryPathTry3D( args
.getValue( 0 ) );
211 Concrete::Length tiebreakerVal
= Concrete::ZERO_LENGTH
;
212 if( tiebreaker
!= NullPtr
< const Lang::Length
>( ) )
214 tiebreakerVal
= tiebreaker
->get( );
216 Kernel::ContRef cont
= evalState
->cont_
;
217 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath3D( evalState
->dyn_
->getGraphicsState( ), path
, "f", tiebreakerVal
) ),
221 catch( const NonLocalExit::NotThisType
& ball
)
223 /* Wrong type; never mind!.. but see below!
229 typedef const Lang::MultiPath2D ArgType
;
230 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
231 if( tiebreaker
!= NullPtr
< const Lang::Length
>( ) )
233 throw Exceptions::CoreOutOfRange( title_
, args
, 1, "The tiebreaker may not specified for 2D paths." );
235 Kernel::ContRef cont
= evalState
->cont_
;
236 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, "f" ) ),
240 catch( const NonLocalExit::NotThisType
& ball
)
242 /* Wrong type; never mind!.. but see below!
248 typedef const Lang::MultiPath3D ArgType
;
249 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
250 Concrete::Length tiebreakerVal
= Concrete::ZERO_LENGTH
;
251 if( tiebreaker
!= NullPtr
< const Lang::Length
>( ) )
253 tiebreakerVal
= tiebreaker
->get( );
255 Kernel::ContRef cont
= evalState
->cont_
;
256 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath3D( evalState
->dyn_
->getGraphicsState( ), path
, "f", tiebreakerVal
) ),
260 catch( const NonLocalExit::NotThisType
& ball
)
262 /* Wrong type; never mind!.. but see below!
266 std::cerr
<< "Throwing in fill." << std::endl
;
267 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::MultiPath2D::staticTypeName( ), Lang::MultiPath3D::staticTypeName( ) ) );
271 class Core_fillstar
: public Lang::CoreFunction
274 Core_fillstar( const char * title
) : CoreFunction( title
) { }
276 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
278 const size_t ARITY
= 1;
279 CHECK_ARITY( args
, ARITY
, title_
);
283 typedef const Lang::ElementaryPath2D ArgType
;
284 RefCountPtr
< ArgType
> path
= Helpers::elementaryPathTry2D( args
.getValue( 0 ) );
285 Kernel::ContRef cont
= evalState
->cont_
;
286 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, "f*" ) ),
290 catch( const NonLocalExit::NotThisType
& ball
)
292 /* Wrong type; never mind!.. but see below!
298 typedef const Lang::MultiPath2D ArgType
;
299 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
300 Kernel::ContRef cont
= evalState
->cont_
;
301 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, "f*" ) ),
305 catch( const NonLocalExit::NotThisType
& ball
)
307 /* Wrong type; never mind!.. but see below!
311 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::MultiPath2D::staticTypeName( ) ) );
315 class Core_facetnormal
: public Lang::CoreFunction
318 Core_facetnormal( const char * title
)
319 : CoreFunction( title
, new Kernel::EvaluatedFormals( title
, true ) )
321 formals_
->appendEvaluatedCoreFormal( "location", Kernel::THE_SLOT_VARIABLE
);
322 formals_
->appendEvaluatedCoreFormal( "normal", Kernel::THE_SLOT_VARIABLE
);
326 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
328 args
.applyDefaults( );
330 typedef const Lang::Coords3D LocationType
;
331 typedef const Lang::FloatTriple NormalType
;
333 RefCountPtr
< LocationType
> location
= Helpers::down_cast_CoreArgument
< LocationType
>( title_
, args
, 0, callLoc
, true );
334 RefCountPtr
< NormalType
> normal
= Helpers::down_cast_CoreArgument
< NormalType
>( title_
, args
, 1, callLoc
, true );
336 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
338 Kernel::ContRef cont
= evalState
->cont_
;
340 RefCountPtr
< const Lang::Color
> nonStroking
= evalState
->dyn_
->getGraphicsState( )->nonStrokingColor_
;
342 /* If both @nonstroking and @autointensity are Gray, then we create a FacetNormalGray, otherwise colors are converted when needed to RGB so that we can create
348 typedef const Lang::Gray ColorType
;
349 RefCountPtr
< ColorType
> lightMultiply
= Helpers::try_cast_CoreArgument
< ColorType
>( nonStroking
);
351 cont
->takeValue( Kernel::ValueRef( new Lang::FacetNormalGray( Concrete::Coords3D( location
->x_
.get( ),
353 location
->z_
.get( ) ),
354 facetState
->reflections_
,
355 Concrete::UnitFloatTriple( normal
->x_
, normal
->y_
, normal
->z_
),
356 lightMultiply
->components( ),
357 facetState
->autoScattering_
,
358 Helpers::try_cast_CoreArgument
< ColorType
>( facetState
->autoIntensity_
)->components( ) ) ),
362 catch( const NonLocalExit::NotThisType
& ball
)
364 /* Wrong type; never mind!.. but see below!
368 // When we reach here, we shall try to convert all colors to RGB.
370 typedef const Lang::RGB ColorType
;
371 Concrete::RGB
lightMultiply( 0, 0, 0 );
374 lightMultiply
= Helpers::try_cast_CoreArgument
< ColorType
>( nonStroking
)->components( );
377 catch( const NonLocalExit::NotThisType
& ball
)
379 /* Wrong type; never mind!.. but see below!
384 double a
= Helpers::try_cast_CoreArgument
< const Lang::Gray
>( nonStroking
)->components( ).gr_
;
385 lightMultiply
= Concrete::RGB( a
, a
, a
);
388 catch( const NonLocalExit::NotThisType
& ball
)
390 /* Wrong type; never mind!.. but see below!
393 throw Exceptions::CoreDynamicTypeMismatch( callLoc
, title_
, Lang::DYNAMIC_VARIABLE_ID_NONSTROKING
,
394 nonStroking
->getTypeName( ),
395 Helpers::typeSetString( Lang::Gray::staticTypeName( ), Lang::RGB::staticTypeName( ) ) );
398 Concrete::RGB
autoIntensity( 0, 0, 0 );
401 autoIntensity
= Helpers::try_cast_CoreArgument
< ColorType
>( facetState
->autoIntensity_
)->components( );
404 catch( const NonLocalExit::NotThisType
& ball
)
406 /* Wrong type; never mind!.. but see below!
411 double a
= Helpers::try_cast_CoreArgument
< const Lang::Gray
>( facetState
->autoIntensity_
)->components( ).gr_
;
412 autoIntensity
= Concrete::RGB( a
, a
, a
);
415 catch( const NonLocalExit::NotThisType
& ball
)
417 /* Wrong type; never mind!.. but see below!
420 throw Exceptions::CoreDynamicTypeMismatch( callLoc
, title_
, Lang::DYNAMIC_VARIABLE_ID_AUTOINTENSITY
,
421 nonStroking
->getTypeName( ),
422 Helpers::typeSetString( Lang::Gray::staticTypeName( ), Lang::RGB::staticTypeName( ) ) );
425 cont
->takeValue( Kernel::ValueRef( new Lang::FacetNormalRGB( Concrete::Coords3D( location
->x_
.get( ),
427 location
->z_
.get( ) ),
428 facetState
->reflections_
,
429 Concrete::UnitFloatTriple( normal
->x_
, normal
->y_
, normal
->z_
),
431 facetState
->autoScattering_
,
438 class Core_facet
: public Lang::CoreFunction
441 Core_facet( const char * title
)
442 : CoreFunction( title
, new Kernel::EvaluatedFormals( title
, true ) )
444 formals_
->appendEvaluatedCoreFormal( "path", Kernel::THE_SLOT_VARIABLE
);
445 formals_
->appendEvaluatedCoreFormal( "n1", Kernel::THE_VOID_VARIABLE
);
446 formals_
->appendEvaluatedCoreFormal( "n2", Kernel::THE_VOID_VARIABLE
);
447 formals_
->appendEvaluatedCoreFormal( "n3", Kernel::THE_VOID_VARIABLE
);
448 formals_
->appendEvaluatedCoreFormal( "tiebreaker", Kernel::VariableHandle( new Kernel::Variable( RefCountPtr
< const Lang::Value
>( new Lang::Length( Concrete::ZERO_LENGTH
) ) ) ) );
449 formals_
->appendEvaluatedCoreFormal( "double", Kernel::THE_VOID_VARIABLE
);
453 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
455 args
.applyDefaults( );
457 // Note that the <double> defaults to false if and only if there is at least one normal specifyed, and all normals agree on what is the outward normal.
459 typedef const Lang::ElementaryPath3D PathType
;
460 typedef const Lang::FacetNormalGray GrayNormalType
;
461 typedef const Lang::FacetNormalRGB RGBNormalType
;
462 typedef const Lang::Length TiebreakerType
;
463 typedef const Lang::Boolean DoubleSidedType
;
465 RefCountPtr
< PathType
> path
= Helpers::elementaryPathCast3D( title_
, args
, 0, callLoc
);
468 bool foundColor
= false;
469 size_t numNormals
= 0;
470 RefCountPtr
< GrayNormalType
> nGray1
= RefCountPtr
< GrayNormalType
>( NullPtr
< GrayNormalType
>( ) );
471 RefCountPtr
< GrayNormalType
> nGray2
= RefCountPtr
< GrayNormalType
>( NullPtr
< GrayNormalType
>( ) );
472 RefCountPtr
< GrayNormalType
> nGray3
= RefCountPtr
< GrayNormalType
>( NullPtr
< GrayNormalType
>( ) );
473 RefCountPtr
< RGBNormalType
> nRGB1
= RefCountPtr
< RGBNormalType
>( NullPtr
< RGBNormalType
>( ) );
474 RefCountPtr
< RGBNormalType
> nRGB2
= RefCountPtr
< RGBNormalType
>( NullPtr
< RGBNormalType
>( ) );
475 RefCountPtr
< RGBNormalType
> nRGB3
= RefCountPtr
< RGBNormalType
>( NullPtr
< RGBNormalType
>( ) );
476 Concrete::UnitFloatTriple
d1( 0, 0, 0, 1. );
477 Concrete::UnitFloatTriple
d2( 0, 0, 0, 1. );
478 Concrete::UnitFloatTriple
d3( 0, 0, 0, 1. );
481 typedef GrayNormalType NormalType
;
482 nGray1
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 1 ), true );
483 nGray2
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 2 ), true );
484 nGray3
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 3 ), true );
485 // If we reach here, numNormals will be zero.
486 if( nGray1
!= NullPtr
< NormalType
>( ) )
488 d1
= nGray1
->normal( );
491 if( nGray2
!= NullPtr
< NormalType
>( ) )
495 throw Exceptions::CoreOutOfRange( title_
, args
, 2, "The normal n1 must be provided before providing n2." );
497 d2
= nGray2
->normal( );
500 if( nGray3
!= NullPtr
< NormalType
>( ) )
504 throw Exceptions::CoreOutOfRange( title_
, args
, 2, "The normals n1 and n2 must be provided before providing n3." );
506 d3
= nGray3
->normal( );
512 catch( const NonLocalExit::NotThisType
& ball
)
514 /* Wrong type; never mind!.. but see below!
521 typedef RGBNormalType NormalType
;
522 nRGB1
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 1 ), true );
523 nRGB2
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 2 ), true );
524 nRGB3
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 3 ), true );
525 // If we reach here, numNormals will be zero.
526 if( nRGB1
!= NullPtr
< NormalType
>( ) )
529 d1
= nRGB1
->normal( );
531 if( nRGB2
!= NullPtr
< NormalType
>( ) )
535 throw Exceptions::CoreOutOfRange( title_
, args
, 2, "The normal n1 must be provided before providing n2." );
538 d2
= nRGB2
->normal( );
540 if( nRGB3
!= NullPtr
< NormalType
>( ) )
544 throw Exceptions::CoreOutOfRange( title_
, args
, 2, "The normals n1 and n2 must be provided before providing n3." );
547 d3
= nRGB3
->normal( );
551 catch( const NonLocalExit::NotThisType
& ball
)
553 /* Wrong type; never mind!.. but see below!
559 throw Exceptions::MiscellaneousRequirement( "The procided facet normals must either be all gray or all RGB." );
561 RefCountPtr
< const Lang::Color
> nonStroking
= evalState
->dyn_
->getGraphicsState( )->nonStrokingColor_
;
562 if( numNormals
== 0 )
564 isRGB
= dynamic_cast< const Lang::RGB
* >( nonStroking
.getPtr( ) ) != 0;
566 dynamic_cast< const Lang::Gray
* >( nonStroking
.getPtr( ) ) == 0 )
568 throw Exceptions::CoreDynamicTypeMismatch( callLoc
, title_
, Lang::DYNAMIC_VARIABLE_ID_NONSTROKING
,
569 nonStroking
->getTypeName( ),
570 Helpers::typeSetString( Lang::Gray::staticTypeName( ), Lang::RGB::staticTypeName( ) ) );
574 RefCountPtr
< TiebreakerType
> tiebreaker
= Helpers::down_cast_CoreArgument
< TiebreakerType
>( title_
, args
, 4, callLoc
);
575 RefCountPtr
< DoubleSidedType
> doubleSided
= Helpers::down_cast_CoreArgument
< DoubleSidedType
>( title_
, args
, 5, callLoc
, true );
577 if( path
->size( ) < 3 )
579 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "A facet path must have at least 3 points." );
581 if( ! path
->isClosed( ) )
583 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "A facet path must be closed." );
586 for( PathType::const_iterator i
= path
->begin( ); i
!= path
->end( ); ++i
)
588 if( (*i
)->front_
!= (*i
)->mid_
|| (*i
)->rear_
!= (*i
)->mid_
)
590 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "A facet path must be a polygon." );
595 Kernel::ContRef cont
= evalState
->cont_
;
597 Concrete::Coords3D
p0( 0, 0, 0 );
598 Concrete::Coords3D
p1( 0, 0, 0 );
599 Concrete::Coords3D
p2( 0, 0, 0 );
600 path
->getRepresentativePoints( Lang::THE_3D_IDENTITY
, & p0
, & p1
, & p2
);
602 Concrete::UnitFloatTriple
normal( 1., 0., 0., 1. );
605 normal
= Concrete::crossDirection( p2
- p0
, p1
- p0
);
607 catch( const NonLocalExit::CrossDirectionOfParallel
& ball
)
609 // This means that the crossDirection called failed because the vectors were parallel.
610 // A polygon of lower dimension is invisible, so we may just return an empty object.
611 cont
->takeValue( Lang::THE_NULL3D
,
617 if( doubleSided
!= NullPtr
< DoubleSidedType
>( ) )
619 isDoubleSided
= doubleSided
->val_
;
623 if( numNormals
== 0 )
625 isDoubleSided
= true;
629 bool allAgree
= true;
630 bool n1Agree
= Concrete::inner( normal
, d1
) > 0;
631 if( d2
.normSquaredThatOughtToBeOne( ) > 0.5 )
633 allAgree
= allAgree
&& ( ( Concrete::inner( normal
, d2
) > 0 ) == n1Agree
);
635 if( d3
.normSquaredThatOughtToBeOne( ) > 0.5 )
637 allAgree
= allAgree
&& ( ( Concrete::inner( normal
, d3
) > 0 ) == n1Agree
);
643 normal
= normal
.reverse( );
645 isDoubleSided
= false;
649 std::cerr
<< "Warning: A facet without explicitly specified double-sidedness had normals pointing in crazy directions, making it double sided." << std::endl
;
650 isDoubleSided
= true;
657 typedef RGBNormalType NormalType
;
658 RefCountPtr
< NormalType
> n1
= nRGB1
;
659 RefCountPtr
< NormalType
> n2
= nRGB2
;
660 RefCountPtr
< NormalType
> n3
= nRGB3
;
661 RefCountPtr
< const Computation::FacetInterpolatorRGB
> interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>( NullPtr
< const Computation::FacetInterpolatorRGB
>( ) );
663 if( numNormals
== 0 )
665 typedef const Lang::RGB ColorType
;
666 RefCountPtr
< ColorType
> lightMultiply
= Helpers::down_cast_CoreDynamic
< ColorType
>( title_
, Lang::DYNAMIC_VARIABLE_ID_NONSTROKING
, nonStroking
, callLoc
);
667 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
669 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>
670 ( new Computation::FacetInterpolatorRGB1
671 ( RefCountPtr
< const Lang::FacetNormalRGB
>
672 ( new Lang::FacetNormalRGB
673 ( (1./3)*( p0
+ p1
+ p2
),
674 facetState
->reflections_
,
676 lightMultiply
->components( ),
677 facetState
->autoScattering_
,
678 Helpers::down_cast_CoreDynamic
< ColorType
>( title_
, Lang::DYNAMIC_VARIABLE_ID_AUTOINTENSITY
, facetState
->autoIntensity_
, callLoc
)->components( ) ) ) ) );
680 else if( numNormals
== 1 )
682 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>
683 ( new Computation::FacetInterpolatorRGB1( n1
) );
685 else if( numNormals
== 2 )
687 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>
688 ( new Computation::FacetInterpolatorRGB2( n1
, n2
) );
690 else if( numNormals
== 3 )
692 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>
693 ( new Computation::FacetInterpolatorRGB3( n1
, n2
, n3
) );
697 throw Exceptions::InternalError( "Number of facet normals is out of range!" );
700 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
702 cont
->takeValue( Kernel::ValueRef( new Lang::SingleSided3DRGB( path
, interpolator
,
703 ! isDoubleSided
, // Note that this argument refers to single-sidedness
704 normal
, Concrete::inner( normal
, p0
),
706 facetState
->viewResolution_
,
707 facetState
->shadeOrder_
) ),
712 typedef GrayNormalType NormalType
;
713 RefCountPtr
< NormalType
> n1
= nGray1
;
714 RefCountPtr
< NormalType
> n2
= nGray2
;
715 RefCountPtr
< NormalType
> n3
= nGray3
;
716 RefCountPtr
< const Computation::FacetInterpolatorGray
> interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>( NullPtr
< const Computation::FacetInterpolatorGray
>( ) );
718 if( numNormals
== 0 )
720 typedef const Lang::Gray ColorType
;
721 RefCountPtr
< ColorType
> lightMultiply
= Helpers::down_cast_CoreDynamic
< ColorType
>( title_
, Lang::DYNAMIC_VARIABLE_ID_NONSTROKING
, nonStroking
, callLoc
);
722 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
724 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>
725 ( new Computation::FacetInterpolatorGray1
726 ( RefCountPtr
< const Lang::FacetNormalGray
>
727 ( new Lang::FacetNormalGray
728 ( (1./3)*( p0
+ p1
+ p2
),
729 facetState
->reflections_
,
731 lightMultiply
->components( ),
732 facetState
->autoScattering_
,
733 Helpers::down_cast_CoreDynamic
< ColorType
>( title_
, Lang::DYNAMIC_VARIABLE_ID_AUTOINTENSITY
, facetState
->autoIntensity_
, callLoc
)->components( ) ) ) ) );
736 else if( numNormals
== 1 )
738 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>
739 ( new Computation::FacetInterpolatorGray1( n1
) );
741 else if( numNormals
== 2 )
743 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>
744 ( new Computation::FacetInterpolatorGray2( n1
, n2
) );
746 else if( numNormals
== 3 )
748 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>
749 ( new Computation::FacetInterpolatorGray3( n1
, n2
, n3
) );
753 throw Exceptions::InternalError( "Number of facet normals is out of range!" );
756 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
758 cont
->takeValue( Kernel::ValueRef( new Lang::SingleSided3DGray( path
, interpolator
,
759 ! isDoubleSided
, // Note that this argument refers to single-sidedness
760 normal
, Concrete::inner( normal
, p0
),
762 facetState
->viewResolution_
,
763 facetState
->shadeOrder_
) ),
769 class Core_from3Dto2D
: public Lang::CoreFunction
772 Core_from3Dto2D( const char * title
) : CoreFunction( title
) { }
774 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
776 const size_t ARITY
= 1;
777 CHECK_ARITY( args
, ARITY
, title_
);
779 typedef const Lang::Geometric3D ArgType
;
780 RefCountPtr
< ArgType
> obj
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
);
782 Kernel::ContRef cont
= evalState
->cont_
;
783 cont
->takeValue( obj
->to2D( evalState
->dyn_
, obj
),
788 class Core_from2Dto3D
: public Lang::CoreFunction
791 Core_from2Dto3D( const char * title
) : CoreFunction( title
) { }
793 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
795 const size_t ARITY
= 1;
796 CHECK_ARITY( args
, ARITY
, title_
);
798 typedef const Lang::Geometric2D ArgType
;
799 RefCountPtr
< ArgType
> obj
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
);
801 Kernel::ContRef cont
= evalState
->cont_
;
802 cont
->takeValue( obj
->to3D( obj
),
807 class Core_facing2Din3D
: public Lang::CoreFunction
810 Core_facing2Din3D( const char * title
)
811 : CoreFunction( title
, new Kernel::EvaluatedFormals( title
, true ) )
813 formals_
->appendEvaluatedCoreFormal( "obj", Kernel::THE_SLOT_VARIABLE
);
814 formals_
->appendEvaluatedCoreFormal( "scale", Kernel::VariableHandle( new Kernel::Variable( Lang::THE_FALSE
) ) );
815 formals_
->appendEvaluatedCoreFormal( "distort", Kernel::VariableHandle( new Kernel::Variable( Lang::THE_FALSE
) ) );
818 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
820 args
.applyDefaults( );
824 typedef const Lang::Drawable2D ArgType
;
825 Kernel::ContRef cont
= evalState
->cont_
;
826 cont
->takeValue( Kernel::ValueRef( new Lang::Facing2Din3D( Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) ),
827 Helpers::down_cast_CoreArgument
< const Lang::Boolean
>( title_
, args
, 1, callLoc
)->val_
,
828 Helpers::down_cast_CoreArgument
< const Lang::Boolean
>( title_
, args
, 2, callLoc
)->val_
) ),
832 catch( const NonLocalExit::NotThisType
& ball
)
834 /* Wrong type; never mind!.. but see below!
840 typedef const Lang::Function ArgType
;
841 Kernel::ContRef cont
= evalState
->cont_
;
842 /* The scale and distort arguments will simply be ignored.
844 cont
->takeValue( Kernel::ValueRef( new Lang::FacingFunction3D( evalState
->dyn_
, Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) ) ) ),
848 catch( const NonLocalExit::NotThisType
& ball
)
850 /* Wrong type; never mind!.. but see below!
854 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::Drawable2D::staticTypeName( ), Lang::Function::staticTypeName( ) ) );
858 class Core_bboxed
: public Lang::CoreFunction
861 Core_bboxed( const char * title
) : CoreFunction( title
) { }
863 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
865 const size_t ARITY
= 2;
866 CHECK_ARITY( args
, ARITY
, title_
);
870 typedef const Lang::Drawable2D ArgType1
;
871 RefCountPtr
< ArgType1
> obj
= Helpers::down_cast_CoreArgument
< ArgType1
>( title_
, args
, argsi
, callLoc
);
875 typedef const Lang::ElementaryPath2D ArgType2
;
876 RefCountPtr
< ArgType2
> p
= Helpers::elementaryPathCast2D( title_
, args
, argsi
, callLoc
);
878 Kernel::ContRef cont
= evalState
->cont_
;
879 cont
->takeValue( Kernel::ValueRef( new Lang::BBoxed2D( obj
, p
) ),
884 class Core_clip
: public Lang::CoreFunction
886 const char * clipCommand_
;
888 Core_clip( const char * title
, const char * clipCommand
) : CoreFunction( title
), clipCommand_( clipCommand
) { }
890 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
892 const size_t ARITY
= 2;
893 CHECK_ARITY( args
, ARITY
, title_
);
897 typedef const Lang::Drawable2D ArgType1
;
898 RefCountPtr
< ArgType1
> obj
= Helpers::down_cast_CoreArgument
< ArgType1
>( title_
, args
, argsi
, callLoc
);
900 RefCountPtr
< Lang::Clipped2D
> res( new Lang::Clipped2D( obj
, clipCommand_
) );
905 typedef const Lang::ElementaryPath2D ArgType
;
906 RefCountPtr
< ArgType
> path
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
907 res
->addSubPath( path
);
910 catch( const NonLocalExit::NotThisType
& ball
)
912 /* Wrong type; never mind!.. but see below!
918 typedef const Lang::SoftMask ArgType
;
919 RefCountPtr
< ArgType
> mask
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( argsi
) );
920 Kernel::ContRef cont
= evalState
->cont_
;
921 cont
->takeValue( RefCountPtr
< Lang::SoftMasked2D
>( new Lang::SoftMasked2D( obj
, mask
) ),
925 catch( const NonLocalExit::NotThisType
& ball
)
927 /* Wrong type; never mind!.. but see below!
933 typedef const Lang::MultiPath2D ArgType
;
934 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( argsi
) );
935 for( Lang::MultiPath2D::const_iterator i
= path
->begin( ); i
!= path
->end( ); ++i
)
938 typedef const Lang::ElementaryPath2D ArgType
;
939 RefCountPtr
< ArgType
> subpath
= (*i
).down_cast
< ArgType
>( );
940 if( subpath
!= NullPtr
< ArgType
>( ) )
942 res
->addSubPath( subpath
);
948 typedef const Lang::Connection2D ArgType
;
949 ArgType
* subpath
= dynamic_cast< ArgType
* >( (*i
).getPtr( ) );
952 res
->addSubPath( subpath
->getElementaryPath( ) );
956 throw Exceptions::InternalError( "clip: Encountered a subpath of unexpected type" );
960 catch( const NonLocalExit::NotThisType
& ball
)
962 /* Wrong type; never mind!.. but see below!
966 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::MultiPath2D::staticTypeName( ) ) );
969 Kernel::ContRef cont
= evalState
->cont_
;
970 cont
->takeValue( res
,
984 class ArrowheadReceiverFormals2D
: public Kernel::EvaluatedFormals
987 ArrowheadReceiverFormals2D( )
988 : Kernel::EvaluatedFormals( "< Arrowhead receiver >", true )
990 appendEvaluatedCoreFormal( "picture", Kernel::THE_SLOT_VARIABLE
);
991 appendEvaluatedCoreFormal( "cut", Kernel::VariableHandle( new Kernel::Variable( RefCountPtr
< const Lang::Value
>( new Lang::Length( 0 ) ) ) ) );
995 ArrowheadReceiverFormals2D theArrowheadReceiverFormals2D
;
997 class Stroke2DCont_tail
: public Kernel::ForcedStructureContinuation
999 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1000 RefCountPtr
< const Lang::ElementaryPath2D
> path_
;
1001 Kernel::PassedEnv env_
;
1002 Kernel::PassedDyn dyn_
;
1003 Kernel::ContRef cont_
;
1005 Stroke2DCont_tail( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
,
1006 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1007 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), env_( env
), dyn_( dyn
), cont_( cont
)
1009 virtual ~Stroke2DCont_tail( ) { }
1010 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1012 /* Argument 0: picture
1015 Kernel::Arguments
args( & theArrowheadReceiverFormals2D
);
1016 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1017 args
.applyDefaults( );
1019 typedef const Lang::Drawable2D ArgType0
;
1020 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_CoreArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1022 typedef const Lang::Length ArgType1
;
1023 RefCountPtr
< ArgType1
> cutTail
= Helpers::down_cast_CoreArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1025 if( cutTail
->get( ) < 0 )
1027 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow tail cut length was negative." ) );
1029 else if( cutTail
->get( ) == 0 )
1031 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1032 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, path_
, "S" ) ) ),
1037 Concrete::SplineTime t1
= path_
->arcTime( cutTail
->get( ) );
1038 Concrete::SplineTime
t2( HUGE_VAL
);
1039 RefCountPtr
< const Lang::ElementaryPath2D
> subpath
= path_
->subpath( t1
, t2
);
1040 if( ! subpath
->empty( ) )
1042 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1043 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, subpath
, "S" ) ) ),
1048 cont_
->takeValue( picture
,
1054 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
1056 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "2D stroke's tail" ) );
1057 cont_
->backTrace( trace
);
1059 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1061 cont_
->gcMark( marked
);
1065 class Stroke2DCont_head
: public Kernel::ForcedStructureContinuation
1067 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1068 RefCountPtr
< const Lang::ElementaryPath2D
> path_
;
1069 Kernel::PassedEnv env_
;
1070 Kernel::PassedDyn dyn_
;
1071 Kernel::ContRef cont_
;
1073 Stroke2DCont_head( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
,
1074 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1075 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), env_( env
), dyn_( dyn
), cont_( cont
)
1077 virtual ~Stroke2DCont_head( ) { }
1078 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1080 /* Argument 0: picture
1083 Kernel::Arguments
args( & theArrowheadReceiverFormals2D
);
1084 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1085 args
.applyDefaults( );
1087 typedef const Lang::Drawable2D ArgType0
;
1088 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_CoreArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1090 typedef const Lang::Length ArgType1
;
1091 RefCountPtr
< ArgType1
> cutHead
= Helpers::down_cast_CoreArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1093 if( cutHead
->get( ) < 0 )
1095 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow head cut length was negative." ) );
1097 else if( cutHead
->get( ) == 0 )
1099 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1100 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, path_
, "S" ) ) ),
1105 Concrete::SplineTime
t1( 0 );
1106 Concrete::SplineTime t2
= path_
->arcTime( path_
->arcLength( ) - cutHead
->get( ) );
1107 RefCountPtr
< const Lang::ElementaryPath2D
> subpath
= path_
->subpath( t1
, t2
);
1108 if( ! subpath
->empty( ) )
1110 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1111 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, subpath
, "S" ) ) ),
1116 cont_
->takeValue( picture
,
1121 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
1123 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "2D stroke's head" ) );
1124 cont_
->backTrace( trace
);
1126 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1128 cont_
->gcMark( marked
);
1132 class Stroke2DCont_both2
: public Kernel::ForcedStructureContinuation
1134 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1135 RefCountPtr
< const Lang::ElementaryPath2D
> path_
;
1136 RefCountPtr
< const Lang::Drawable2D
> tail_
;
1137 Lang::Length cutTail_
;
1138 Kernel::PassedEnv env_
;
1139 Kernel::PassedDyn dyn_
;
1140 Kernel::ContRef cont_
;
1142 Stroke2DCont_both2( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
,
1143 const RefCountPtr
< const Lang::Drawable2D
> & tail
, Lang::Length cutTail
,
1144 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1145 : Kernel::ForcedStructureContinuation( "Stroke's arrow head receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), tail_( tail
), cutTail_( cutTail
), env_( env
), dyn_( dyn
), cont_( cont
)
1147 virtual ~Stroke2DCont_both2( ) { }
1148 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1150 /* Argument 0: picture
1153 Kernel::Arguments
args( & theArrowheadReceiverFormals2D
);
1154 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1155 args
.applyDefaults( );
1157 typedef const Lang::Drawable2D ArgType0
;
1158 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_CoreArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1160 typedef const Lang::Length ArgType1
;
1161 RefCountPtr
< ArgType1
> cutHead
= Helpers::down_cast_CoreArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1163 if( cutHead
->get( ) < 0 )
1165 throw Exceptions::MiscellaneousRequirement( strrefdup( "Aarrow head cut length was negative." ) );
1168 if( cutTail_
.get( ) == 0 && cutHead
->get( ) == 0 )
1170 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1172 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, path_
, "S" ) ) ),
1177 Concrete::SplineTime
t1( 0 );
1178 if( cutTail_
.get( ) > 0 )
1180 t1
= path_
->arcTime( cutTail_
.get( ) );
1183 Concrete::SplineTime
t2( HUGE_VAL
);
1184 if( cutHead
->get( ) > 0 )
1186 t2
= path_
->arcTime( path_
->arcLength( ) - cutHead
->get( ) );
1189 RefCountPtr
< const Lang::ElementaryPath2D
> subpath
= path_
->subpath( t1
, t2
);
1191 if( ! subpath
->empty( ) )
1193 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1195 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, subpath
, "S" ) ) ),
1200 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1206 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
1208 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "2D stroke's head & tail, second" ) );
1209 cont_
->backTrace( trace
);
1211 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1213 const_cast< Lang::Drawable2D
* >( tail_
.getPtr( ) )->gcMark( marked
);
1214 cont_
->gcMark( marked
);
1218 class Stroke2DCont_both1
: public Kernel::ForcedStructureContinuation
1220 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1221 RefCountPtr
< const Lang::ElementaryPath2D
> path_
;
1222 RefCountPtr
< const Lang::Function
> headFunction_
;
1223 Kernel::PassedEnv env_
;
1224 Kernel::PassedDyn dyn_
;
1225 Kernel::ContRef cont_
;
1227 Stroke2DCont_both1( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
,
1228 const RefCountPtr
< const Lang::Function
> & headFunction
,
1229 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1230 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), headFunction_( headFunction
), env_( env
), dyn_( dyn
), cont_( cont
)
1232 virtual ~Stroke2DCont_both1( ) { }
1233 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1235 /* Argument 0: picture
1238 Kernel::Arguments
args( & theArrowheadReceiverFormals2D
);
1239 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1240 args
.applyDefaults( );
1242 typedef const Lang::Drawable2D ArgType0
;
1243 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_CoreArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1245 typedef const Lang::Length ArgType1
;
1246 RefCountPtr
< ArgType1
> cutTail
= Helpers::down_cast_CoreArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1248 if( cutTail
->get( ) < 0 )
1250 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow tail cut length was negative." ) );
1253 evalState
->env_
= env_
;
1254 evalState
->dyn_
= dyn_
;
1255 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke2DCont_both2( graphicsState_
, path_
, picture
, *cutTail
, env_
, dyn_
, cont_
, traceLoc_
) );
1256 headFunction_
->call( evalState
, path_
->reverse( ), traceLoc_
);
1258 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
1260 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "2D stroke's head & tail, first" ) );
1261 cont_
->backTrace( trace
);
1263 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1265 const_cast< Lang::Function
* >( headFunction_
.getPtr( ) )->gcMark( marked
);
1266 dyn_
->gcMark( marked
);
1267 cont_
->gcMark( marked
);
1277 Helpers::stroke_helper_2D( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
, Kernel::Arguments
& args
, bool fill
, const Ast::SourceLocation
& callLoc
)
1279 RefCountPtr
< const Lang::Function
> arrowHead
= args
.getHandle( 1 )->getVal
< const Lang::Function
>( "< core function stroke: head >" );
1280 RefCountPtr
< const Lang::Function
> arrowTail
= args
.getHandle( 2 )->getVal
< const Lang::Function
>( "< core function stroke: tail >" );
1281 if( ( arrowHead
== Lang::THE_NO_ARROW
&&
1282 arrowTail
== Lang::THE_NO_ARROW
) ||
1285 Kernel::ContRef cont
= evalState
->cont_
;
1286 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, fill
? "B" : "S" ) ),
1292 /* The computation must continue outside here since functions are to be called, and resulting graphics collected.
1296 throw Exceptions::NotImplemented( "Arrowheads in fill-stroke command." );
1299 if( arrowTail
== Lang::THE_NO_ARROW
)
1301 /* There's only an arrow at the head.
1303 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke2DCont_head( evalState
->dyn_
->getGraphicsState( ), path
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1304 arrowHead
->call( evalState
, path
->reverse( ), callLoc
);
1308 if( arrowHead
== Lang::THE_NO_ARROW
)
1310 /* There's only an arrow at the tail.
1312 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke2DCont_tail( evalState
->dyn_
->getGraphicsState( ), path
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1313 arrowHead
->call( arrowTail
, evalState
, args
.getHandle( 0 ), callLoc
);
1317 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke2DCont_both1( evalState
->dyn_
->getGraphicsState( ), path
, arrowHead
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1318 arrowTail
->call( arrowTail
, evalState
, args
.getHandle( 0 ), callLoc
);
1328 class ArrowheadReceiverFormals3D
: public Kernel::EvaluatedFormals
1331 ArrowheadReceiverFormals3D( )
1332 : Kernel::EvaluatedFormals( "< Arrowhead receiver >", true )
1334 appendEvaluatedCoreFormal( "picture", Kernel::THE_SLOT_VARIABLE
);
1335 appendEvaluatedCoreFormal( "cut", Kernel::VariableHandle( new Kernel::Variable( RefCountPtr
< const Lang::Value
>( new Lang::Length( 0 ) ) ) ) );
1339 ArrowheadReceiverFormals3D theArrowheadReceiverFormals3D
;
1341 class Stroke3DCont_tail
: public Kernel::ForcedStructureContinuation
1343 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1344 RefCountPtr
< const Lang::ElementaryPath3D
> path_
;
1345 Kernel::PassedEnv env_
;
1346 Kernel::PassedDyn dyn_
;
1347 Kernel::ContRef cont_
;
1349 Stroke3DCont_tail( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
,
1350 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1351 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), env_( env
), dyn_( dyn
), cont_( cont
)
1353 virtual ~Stroke3DCont_tail( ) { }
1354 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1356 /* Argument 0: picture
1359 Kernel::Arguments
args( & theArrowheadReceiverFormals3D
);
1360 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1361 args
.applyDefaults( );
1363 typedef const Lang::Drawable3D ArgType0
;
1364 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_CoreArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1366 typedef const Lang::Length ArgType1
;
1367 RefCountPtr
< ArgType1
> cutTail
= Helpers::down_cast_CoreArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1369 if( cutTail
->get( ) < 0 )
1371 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow tail cut length was negative." ) );
1373 else if( cutTail
->get( ) == 0 )
1375 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1377 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, path_
, "S" ) ) ),
1382 Concrete::SplineTime t1
= path_
->arcTime( cutTail
->get( ) );
1383 Concrete::SplineTime
t2( HUGE_VAL
);
1384 RefCountPtr
< const Lang::ElementaryPath3D
> subpath
= path_
->subpath( t1
, t2
);
1385 if( ! subpath
->empty( ) )
1387 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1389 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, subpath
, "S" ) ) ),
1394 cont_
->takeValue( picture
,
1400 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
1402 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "3D stroke's tail" ) );
1403 cont_
->backTrace( trace
);
1405 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1407 cont_
->gcMark( marked
);
1411 class Stroke3DCont_head
: public Kernel::ForcedStructureContinuation
1413 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1414 RefCountPtr
< const Lang::ElementaryPath3D
> path_
;
1415 Kernel::PassedEnv env_
;
1416 Kernel::PassedDyn dyn_
;
1417 Kernel::ContRef cont_
;
1419 Stroke3DCont_head( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
,
1420 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1421 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), env_( env
), dyn_( dyn
), cont_( cont
)
1423 virtual ~Stroke3DCont_head( ) { }
1424 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1426 /* Argument 0: picture
1429 Kernel::Arguments
args( & theArrowheadReceiverFormals3D
);
1430 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1431 args
.applyDefaults( );
1433 typedef const Lang::Drawable3D ArgType0
;
1434 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_CoreArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1436 typedef const Lang::Length ArgType1
;
1437 RefCountPtr
< ArgType1
> cutHead
= Helpers::down_cast_CoreArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1439 if( cutHead
->get( ) < 0 )
1441 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow head cut length was negative." ) );
1443 else if( cutHead
->get( ) == 0 )
1445 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1447 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, path_
, "S" ) ) ),
1452 Concrete::SplineTime
t1( 0 );
1453 Concrete::SplineTime t2
= path_
->arcTime( path_
->arcLength( ) - cutHead
->get( ) );
1454 RefCountPtr
< const Lang::ElementaryPath3D
> subpath
= path_
->subpath( t1
, t2
);
1455 if( ! subpath
->empty( ) )
1457 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1459 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, subpath
, "S" ) ) ),
1464 cont_
->takeValue( picture
,
1469 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
1471 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "3D stroke's head" ) );
1472 cont_
->backTrace( trace
);
1474 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1476 cont_
->gcMark( marked
);
1480 class Stroke3DCont_both2
: public Kernel::ForcedStructureContinuation
1482 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1483 RefCountPtr
< const Lang::ElementaryPath3D
> path_
;
1484 RefCountPtr
< const Lang::Drawable3D
> tail_
;
1485 Lang::Length cutTail_
;
1486 Kernel::PassedEnv env_
;
1487 Kernel::PassedDyn dyn_
;
1488 Kernel::ContRef cont_
;
1490 Stroke3DCont_both2( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
,
1491 const RefCountPtr
< const Lang::Drawable3D
> & tail
, Lang::Length cutTail
,
1492 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1493 : Kernel::ForcedStructureContinuation( "Stroke's arrow head receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), tail_( tail
), cutTail_( cutTail
), env_( env
), dyn_( dyn
), cont_( cont
)
1495 virtual ~Stroke3DCont_both2( ) { }
1496 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1498 /* Argument 0: picture
1501 Kernel::Arguments
args( & theArrowheadReceiverFormals3D
);
1502 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1503 args
.applyDefaults( );
1505 typedef const Lang::Drawable3D ArgType0
;
1506 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_CoreArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1508 typedef const Lang::Length ArgType1
;
1509 RefCountPtr
< ArgType1
> cutHead
= Helpers::down_cast_CoreArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1511 if( cutHead
->get( ) < 0 )
1513 throw Exceptions::MiscellaneousRequirement( strrefdup( "Aarrow head cut length was negative." ) );
1516 if( cutTail_
.get( ) == 0 && cutHead
->get( ) == 0 )
1518 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1521 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, path_
, "S" ) ) ),
1526 Concrete::SplineTime
t1( 0 );
1527 if( cutTail_
.get( ) > 0 )
1529 t1
= path_
->arcTime( cutTail_
.get( ) );
1532 Concrete::SplineTime
t2( HUGE_VAL
);
1533 if( cutHead
->get( ) > 0 )
1535 t2
= path_
->arcTime( path_
->arcLength( ) - cutHead
->get( ) );
1538 RefCountPtr
< const Lang::ElementaryPath3D
> subpath
= path_
->subpath( t1
, t2
);
1540 if( ! subpath
->empty( ) )
1542 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1545 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, subpath
, "S" ) ) ),
1550 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1557 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
1559 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "3D stroke's head & tail, second" ) );
1560 cont_
->backTrace( trace
);
1562 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1564 const_cast< Lang::Drawable3D
* >( tail_
.getPtr( ) )->gcMark( marked
);
1565 cont_
->gcMark( marked
);
1569 class Stroke3DCont_both1
: public Kernel::ForcedStructureContinuation
1571 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1572 RefCountPtr
< const Lang::ElementaryPath3D
> path_
;
1573 RefCountPtr
< const Lang::Function
> headFunction_
;
1574 Kernel::PassedEnv env_
;
1575 Kernel::PassedDyn dyn_
;
1576 Kernel::ContRef cont_
;
1578 Stroke3DCont_both1( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
,
1579 const RefCountPtr
< const Lang::Function
> & headFunction
,
1580 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1581 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), headFunction_( headFunction
), env_( env
), dyn_( dyn
), cont_( cont
)
1583 virtual ~Stroke3DCont_both1( ) { }
1584 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1586 /* Argument 0: picture
1589 Kernel::Arguments
args( & theArrowheadReceiverFormals3D
);
1590 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1591 args
.applyDefaults( );
1593 typedef const Lang::Drawable3D ArgType0
;
1594 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_CoreArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1596 typedef const Lang::Length ArgType1
;
1597 RefCountPtr
< ArgType1
> cutTail
= Helpers::down_cast_CoreArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1599 if( cutTail
->get( ) < 0 )
1601 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow tail cut length was negative." ) );
1604 evalState
->env_
= env_
;
1605 evalState
->dyn_
= dyn_
;
1606 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke3DCont_both2( graphicsState_
, path_
, picture
, *cutTail
, env_
, dyn_
, cont_
, traceLoc_
) );
1607 headFunction_
->call( evalState
, path_
->reverse( ), traceLoc_
);
1609 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
1611 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "3D stroke's head & tail, first" ) );
1612 cont_
->backTrace( trace
);
1614 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1616 const_cast< Lang::Function
* >( headFunction_
.getPtr( ) )->gcMark( marked
);
1617 dyn_
->gcMark( marked
);
1618 cont_
->gcMark( marked
);
1627 Helpers::stroke_helper_3D( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
, Kernel::Arguments
& args
, bool fill
, const Ast::SourceLocation
& callLoc
)
1629 RefCountPtr
< const Lang::Function
> arrowHead
= args
.getHandle( 1 )->getVal
< const Lang::Function
>( "< core function stroke: head >" );
1630 RefCountPtr
< const Lang::Function
> arrowTail
= args
.getHandle( 2 )->getVal
< const Lang::Function
>( "< core function stroke: tail >" );
1631 if( ( arrowHead
== Lang::THE_NO_ARROW
&&
1632 arrowTail
== Lang::THE_NO_ARROW
) ||
1635 Kernel::ContRef cont
= evalState
->cont_
;
1636 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath3D( evalState
->dyn_
->getGraphicsState( ), path
, fill
? "B" : "S" ) ),
1642 /* The computation must continue outside here since functions are to be called, and resulting graphics collected.
1646 throw Exceptions::NotImplemented( "Arrowheads in fill-stroke command." );
1649 if( arrowTail
== Lang::THE_NO_ARROW
)
1651 /* There's only an arrow at the head.
1653 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke3DCont_head( evalState
->dyn_
->getGraphicsState( ), path
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1654 arrowHead
->call( evalState
, path
->reverse( ), callLoc
);
1658 if( arrowHead
== Lang::THE_NO_ARROW
)
1660 /* There's only an arrow at the tail.
1662 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke3DCont_tail( evalState
->dyn_
->getGraphicsState( ), path
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1663 arrowHead
->call( arrowTail
, evalState
, args
.getHandle( 0 ), callLoc
);
1667 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke3DCont_both1( evalState
->dyn_
->getGraphicsState( ), path
, arrowHead
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1668 arrowTail
->call( arrowTail
, evalState
, args
.getHandle( 0 ), callLoc
);
1680 Kernel::registerCore_draw( Kernel::Environment
* env
)
1682 env
->initDefineCoreFunction( new Lang::Core_spot( "spot" ) );
1683 env
->initDefineCoreFunction( new Lang::Core_stroke( "stroke", false ) );
1684 env
->initDefineCoreFunction( new Lang::Core_stroke( "fillstroke", true ) );
1685 env
->initDefineCoreFunction( new Lang::Core_fill( "fill" ) );
1686 env
->initDefineCoreFunction( new Lang::Core_fillstar( "fillodd" ) );
1687 env
->initDefineCoreFunction( new Lang::Core_facetnormal( "facetnormal" ) );
1688 env
->initDefineCoreFunction( new Lang::Core_facet( "facet" ) );
1690 env
->initDefineCoreFunction( new Lang::Core_bboxed( "bboxed" ) );
1691 env
->initDefineCoreFunction( new Lang::Core_clip( "clip", "W" ) );
1692 env
->initDefineCoreFunction( new Lang::Core_clip( "clipodd", "W*" ) );
1694 env
->initDefineCoreFunction( new Lang::Core_from3Dto2D( "view" ) );
1695 env
->initDefineCoreFunction( new Lang::Core_from2Dto3D( "immerse" ) );
1696 env
->initDefineCoreFunction( new Lang::Core_facing2Din3D( "facing" ) );