Adjust to updated function signature in libpng.
[shapes.git] / source / pathtypes.cc
blob8187b39adf6f34b82201ab9149bb060c9b137502
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 Henrik Tidefelt
19 #include <cmath>
21 #include "shapestypes.h"
22 #include "shapesexceptions.h"
23 #include "astexpr.h"
24 #include "consts.h"
25 #include "globals.h"
26 #include "angleselect.h"
27 #include "astvar.h"
28 #include "astclass.h"
29 #include "continuations.h"
30 #include "dynamicenvironment.h"
32 #include <complex>
33 #include <ctype.h>
34 #include <stack>
36 using namespace Shapes;
37 using namespace std;
40 Concrete::Time
41 Shapes::computeDt( Concrete::Length segLength )
43 double dt = Computation::the_arcdelta / segLength;
44 if( dt < Computation::the_dtMin )
46 if( Computation::dtMinIsError )
48 throw Exceptions::DtMinError( dt );
50 dt = Computation::the_dtMin;
52 return dt;
55 Concrete::Time
56 Shapes::straightLineArcTime( double fraction )
58 typedef std::complex< double > Complex;
59 Complex s( fraction, 0 );
60 const Complex add1iSqrt3( 1, sqrt( 3 ) );
61 const Complex sub1iSqrt3( 1, -sqrt( 3 ) );
62 const Complex tmp = pow( Complex( -1, 0 ) + Complex( 2, 0 ) * ( s + sqrt( ( Complex( -1, 0 ) + s ) * s ) ), 1./3 );
63 return 0.5 + 0.25 * ( (sub1iSqrt3 / tmp ).real( ) + ( add1iSqrt3 * tmp ).real( ) );
64 // const Complex cRes = Complex( 0.5, 0 ) + Complex( 0.25, 0 ) * ( sub1iSqrt3 / tmp + add1iSqrt3 * tmp );
65 // return cRes.real( );
68 Kernel::PolarHandlePromise::PolarHandlePromise( )
69 { }
71 Kernel::PolarHandlePromise::~PolarHandlePromise( )
72 { }
75 Kernel::PolarHandleEmptyPromise::PolarHandleEmptyPromise( )
76 { }
78 Kernel::PolarHandleEmptyPromise::~PolarHandleEmptyPromise( )
79 { }
81 double
82 Kernel::PolarHandleEmptyPromise::force( const Concrete::PathPoint2D * specialUnitP0, const Concrete::PathPoint2D * specialUnitP1, bool reverse ) const
84 std::ostringstream msg;
85 msg << "The empty promise must be replaced before use. Probably related to " << Interaction::DYNAMIC_VARIABLE_PREFIX << Lang::DYNAMIC_VARIABLE_ID_DEFAULT_UNIT << "." ;
86 throw Exceptions::MiscellaneousRequirement( strrefdup( msg ) );
89 void
90 Kernel::PolarHandleEmptyPromise::gcMark( Kernel::GCMarkedSet & marked ) const
95 void
96 Kernel::PolarHandleEmptyPromise::show( std::ostream & os ) const
98 os << "< undefined >" ;
102 Kernel::PolarHandleTruePromise::PolarHandleTruePromise( Kernel::Thunk * thunk )
103 : thunk_( thunk )
106 Kernel::PolarHandleTruePromise::~PolarHandleTruePromise( )
108 delete thunk_;
112 double
113 Kernel::PolarHandleTruePromise::force( const Concrete::PathPoint2D * specialUnitP0, const Concrete::PathPoint2D * specialUnitP1, bool reverse ) const
115 Kernel::ValueRef valUntyped = NullPtr< const Lang::Value >( );
117 /* Note that the use of a StoreValueContinuation relies on valUntyped being alive at the time the continuation is invoked.
119 bool done = false;
120 Kernel::EvalState evalState( 0,
122 NullPtr< Kernel::DynamicEnvironment >( ),
123 Kernel::ContRef( new Kernel::StoreValueContinuation( & valUntyped,
124 Kernel::ContRef( new Kernel::ExitContinuation( & done, thunk_->getExpr( )->loc( ) ) ),
125 thunk_->getExpr( )->loc( ) ) ) );
127 thunk_->force( & evalState, false ); /* note that the dynamic environment is set below, before evaluation begins. "false" means that the thunk may be forced repeatedly */
129 Kernel::SpecialUnitVariables * dynVars = new Kernel::SpecialUnitVariables;
130 dynVars->reverseDirection_ = reverse;
131 dynVars->p0_ = specialUnitP0;
132 dynVars->p1_ = specialUnitP1;
133 evalState.dyn_ = Kernel::PassedDyn( new Kernel::DynamicEnvironment( evalState.dyn_, dynVars ) );
135 while( ! done )
137 evalState.expr_->eval( & evalState );
140 typedef const Lang::Length ArgType;
141 ArgType * valPtr = dynamic_cast< ArgType * >( valUntyped.getPtr( ) );
142 if( valPtr == 0 )
144 throw Exceptions::TypeMismatch( thunk_->getExpr( )->loc( ), valUntyped->getTypeName( ), ArgType::staticTypeName( ) );
147 return valPtr->getScalar( );
150 void
151 Kernel::PolarHandleTruePromise::gcMark( Kernel::GCMarkedSet & marked ) const
153 if( thunk_ != 0 )
155 thunk_->gcMark( marked );
159 void
160 Kernel::PolarHandleTruePromise::show( std::ostream & os ) const
162 os << "Dynamic expression at " << thunk_->getExpr( )->loc( ) ;
166 Lang::PolarHandleBase::PolarHandleBase( )
169 DISPATCHIMPL( PolarHandleBase );
171 Lang::PolarHandleBase::~PolarHandleBase( )
174 RefCountPtr< const Lang::Class > Lang::PolarHandleBase::TypeID( new Lang::SystemFinalClass( strrefdup( "PolarHandle" ) ) );
175 TYPEINFOIMPL( PolarHandleBase );
178 Lang::PolarHandle2D::PolarHandle2D( const RefCountPtr< const Kernel::PolarHandlePromise > & rPromise, double a )
179 : rPromise_( rPromise ), a_( a )
182 DISPATCHIMPL( PolarHandle2D );
184 Lang::PolarHandle2D::~PolarHandle2D( )
187 void
188 Lang::PolarHandle2D::show( std::ostream & os ) const
190 os << "Completely specified" ;
193 void
194 Lang::PolarHandle2D::gcMark( Kernel::GCMarkedSet & marked )
196 rPromise_->gcMark( marked );
200 Lang::PolarHandle2DFree_a::PolarHandle2DFree_a( const RefCountPtr< const Kernel::PolarHandlePromise > & rPromise )
201 : rPromise_( rPromise )
204 DISPATCHIMPL( PolarHandle2DFree_a );
206 Lang::PolarHandle2DFree_a::~PolarHandle2DFree_a( )
209 void
210 Lang::PolarHandle2DFree_a::show( std::ostream & os ) const
212 os << "Free angle, promise pointer: " << rPromise_.getPtr( ) ;
215 void
216 Lang::PolarHandle2DFree_a::gcMark( Kernel::GCMarkedSet & marked )
218 rPromise_->gcMark( marked );
222 Lang::PolarHandle2DFree_r::PolarHandle2DFree_r( const RefCountPtr< const Kernel::PolarHandlePromise > & defaultModulus, double a )
223 : defaultModulus_( defaultModulus ), a_( a )
226 DISPATCHIMPL( PolarHandle2DFree_r );
228 Lang::PolarHandle2DFree_r::~PolarHandle2DFree_r( )
231 void
232 Lang::PolarHandle2DFree_r::show( std::ostream & os ) const
234 os << "Free modulus, angle = " << a_ ;
237 void
238 Lang::PolarHandle2DFree_r::gcMark( Kernel::GCMarkedSet & marked )
240 defaultModulus_->gcMark( marked );
244 Lang::PolarHandle2DFree_ra::PolarHandle2DFree_ra( const RefCountPtr< const Kernel::PolarHandlePromise > & defaultModulus )
245 : defaultModulus_( defaultModulus )
248 DISPATCHIMPL( PolarHandle2DFree_ra );
250 Lang::PolarHandle2DFree_ra::~PolarHandle2DFree_ra( )
253 void
254 Lang::PolarHandle2DFree_ra::show( std::ostream & os ) const
256 os << "Completely free" ;
259 void
260 Lang::PolarHandle2DFree_ra::gcMark( Kernel::GCMarkedSet & marked )
262 defaultModulus_->gcMark( marked );
266 Concrete::PathPoint2D::PathPoint2D( const Concrete::PathPoint2D & orig )
267 : rearState_( orig.rearState_ ), rearAngle_( orig.rearAngle_ ), rearModulus_( orig.rearModulus_ ),
268 rearModulusPromise_( NullPtr< Kernel::PolarHandlePromise >( ) ),
269 frontState_( orig.frontState_ ), frontAngle_( orig.frontAngle_ ), frontModulus_( orig.frontModulus_ ),
270 frontModulusPromise_( NullPtr< Kernel::PolarHandlePromise >( ) ),
271 defaultAngle_( orig.defaultAngle_ )
273 mid_ = new Concrete::Coords2D( *orig.mid_ );
275 if( orig.rear_ != orig.mid_ )
277 rear_ = new Concrete::Coords2D( *orig.rear_ );
279 else
281 rear_ = mid_;
283 if( orig.front_ != orig.mid_ )
285 front_ = new Concrete::Coords2D( *orig.front_ );
287 else
289 front_ = mid_;
293 /* The initial state is set to COMPLETE, even though theoretically, the angle towards the neighboring pathpoints should be computed.
294 * However, by setting the default rearAngle_ and frontAngle_ to NaN, we can replace an atan2 computation by an IS_NAN test.
296 Concrete::PathPoint2D::PathPoint2D( Concrete::Coords2D * mid )
297 : rearState_( COMPLETE ), rearAngle_( std::numeric_limits< double >::signaling_NaN( ) ), rearModulusPromise_( NullPtr< Kernel::PolarHandlePromise >( ) ),
298 frontState_( COMPLETE ), frontAngle_( std::numeric_limits< double >::signaling_NaN( ) ), frontModulusPromise_( NullPtr< Kernel::PolarHandlePromise >( ) ),
299 defaultAngle_( 0 ),
300 rear_( mid ), mid_( mid ), front_( mid )
303 Concrete::PathPoint2D::PathPoint2D( Concrete::Length midx, Concrete::Length midy )
304 : rearState_( COMPLETE ), rearAngle_( std::numeric_limits< double >::signaling_NaN( ) ), rearModulusPromise_( NullPtr< Kernel::PolarHandlePromise >( ) ),
305 frontState_( COMPLETE ), frontAngle_( std::numeric_limits< double >::signaling_NaN( ) ), frontModulusPromise_( NullPtr< Kernel::PolarHandlePromise >( ) ),
306 defaultAngle_( 0 ),
307 rear_( new Concrete::Coords2D( midx, midy ) ), mid_( rear_ ), front_( rear_ )
310 Concrete::PathPoint2D::~PathPoint2D( )
312 if( rear_ != 0 && rear_ != mid_ )
314 delete rear_;
316 if( mid_ != 0 )
318 delete mid_;
320 if( front_ != 0 && front_ != mid_ )
322 delete front_;
326 Concrete::PathPoint2D *
327 Concrete::PathPoint2D::transformed( const Lang::Transform2D & tf ) const
329 Concrete::PathPoint2D * res = new Concrete::PathPoint2D( mid_->transformedPtr( tf ) );
330 if( rear_ != mid_ )
332 res->rear_ = rear_->transformedPtr( tf );
334 if( front_ != mid_ )
336 res->front_ = front_->transformedPtr( tf );
338 return res;
341 Concrete::PathPoint3D *
342 Concrete::PathPoint2D::transformed( const Lang::Transform3D & tf ) const
344 Concrete::PathPoint3D * res = new Concrete::PathPoint3D( mid_->transformedPtr( tf ) );
345 if( rear_ != mid_ )
347 res->rear_ = rear_->transformedPtr( tf );
349 if( front_ != mid_ )
351 res->front_ = front_->transformedPtr( tf );
353 return res;
356 Concrete::PathPoint3D *
357 Concrete::PathPoint2D::typed_to3D( ) const
359 Concrete::PathPoint3D * res = new Concrete::PathPoint3D( *mid_ );
360 if( rear_ != mid_ )
362 res->rear_ = new Concrete::Coords3D( *rear_ );
364 if( front_ != mid_ )
366 res->front_ = new Concrete::Coords3D( *front_ );
368 return res;
372 Concrete::PathPoint3D::PathPoint3D( const Concrete::PathPoint3D & orig )
373 : mid_( new Concrete::Coords3D( *orig.mid_ ) )
375 if( orig.rear_ != orig.mid_ )
377 rear_ = new Concrete::Coords3D( *orig.rear_ );
379 else
381 rear_ = mid_;
384 if( orig.front_ != orig.mid_ )
386 front_ = new Concrete::Coords3D( *orig.front_ );
388 else
390 front_ = mid_;
394 Concrete::PathPoint3D::PathPoint3D( Concrete::Coords3D * mid )
395 : rear_( mid ), mid_( mid ), front_( mid )
398 Concrete::PathPoint3D::PathPoint3D( const Concrete::Coords2D & mid )
399 : rear_( new Concrete::Coords3D( mid ) ), mid_( rear_ ), front_( rear_ )
402 Concrete::PathPoint3D::PathPoint3D( Concrete::Length midx, Concrete::Length midy, Concrete::Length midz )
403 : rear_( new Concrete::Coords3D( midx, midy, midz ) ), mid_( rear_ ), front_( rear_ )
406 Concrete::PathPoint3D::~PathPoint3D( )
408 if( rear_ != 0 && rear_ != mid_ )
410 delete rear_;
412 if( mid_ != 0 )
414 delete mid_;
416 if( front_ != 0 && front_ != mid_ )
418 delete front_;
422 Concrete::PathPoint3D *
423 Concrete::PathPoint3D::transformed( const Lang::Transform3D & tf ) const
425 Concrete::PathPoint3D * res = new Concrete::PathPoint3D( mid_->transformedPtr( tf ) );
426 if( rear_ != mid_ )
428 res->rear_ = rear_->transformedPtr( tf );
430 if( front_ != mid_ )
432 res->front_ = front_->transformedPtr( tf );
434 return res;
437 Concrete::PathPoint2D *
438 Concrete::PathPoint3D::make2D( Concrete::Length eyez ) const
440 Concrete::PathPoint2D * res = new Concrete::PathPoint2D( mid_->make2D( eyez ) );
441 if( rear_ != mid_ )
443 res->rear_ = rear_->make2D( eyez );
445 if( front_ != mid_ )
447 res->front_ = front_->make2D( eyez );
449 return res;
452 Lang::PathPoint2D::PathPoint2D( const Lang::PathPoint2D & orig )
453 : rear_( orig.rear_ ), mid_( orig.mid_ ), front_( orig.front_ )
456 DISPATCHIMPL( PathPoint2D );
458 Lang::PathPoint2D::PathPoint2D( RefCountPtr< const Lang::Coords2D > mid )
459 : rear_( NullPtr< Lang::Value >( ) ), mid_( mid ), front_( NullPtr< Lang::Value >( ) )
462 Kernel::VariableHandle
463 Lang::PathPoint2D::getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const
465 if( strcmp( fieldID, "mid" ) == 0 )
467 return Kernel::VariableHandle( new Kernel::Variable( mid_ ) );
469 if( strcmp( fieldID, "rear" ) == 0 )
471 return Kernel::VariableHandle( new Kernel::Variable( rear_ ) );
473 if( strcmp( fieldID, "front" ) == 0 )
475 return Kernel::VariableHandle( new Kernel::Variable( front_ ) );
477 throw Exceptions::NonExistentMember( getTypeName( ), fieldID );
480 RefCountPtr< const Lang::Geometric2D >
481 Lang::PathPoint2D::transformed( const Lang::Transform2D & tf, const RefCountPtr< const Lang::Geometric2D > & self ) const
483 throw Exceptions::MiscellaneousRequirement( strrefdup( "A pathpoint by itself cannot be transformed." ) );
486 RefCountPtr< const Lang::Geometric3D >
487 Lang::PathPoint2D::to3D( const RefCountPtr< const Lang::Geometric2D > & self ) const
489 throw Exceptions::MiscellaneousRequirement( strrefdup( "A 2D pathpoint by itself cannot go 3D." ) );
492 void
493 Lang::PathPoint2D::gcMark( Kernel::GCMarkedSet & marked )
496 Lang::Value * tmp = const_cast< Lang::Value * >( rear_.getPtr( ) );
497 if( tmp != 0 )
499 tmp->gcMark( marked );
503 const_cast< Lang::Coords2D * >( mid_.getPtr( ) )->gcMark( marked );
506 Lang::Value * tmp = const_cast< Lang::Value * >( front_.getPtr( ) );
507 if( tmp != 0 )
509 tmp->gcMark( marked );
515 RefCountPtr< const Lang::Class > Lang::PathPoint2D::TypeID( new Lang::SystemFinalClass( strrefdup( "PathPoint" ) ) );
516 TYPEINFOIMPL( PathPoint2D );
519 Lang::PathPoint3D::PathPoint3D( const Lang::PathPoint3D & orig )
520 : rear_( orig.rear_ ), mid_( orig.mid_ ), front_( orig.front_ )
523 DISPATCHIMPL( PathPoint3D );
525 Lang::PathPoint3D::PathPoint3D( const RefCountPtr< const Lang::Coords3D > & mid )
526 : rear_( NullPtr< Lang::Coords3D >( ) ), mid_( mid ), front_( NullPtr< Lang::Coords3D >( ) )
529 Kernel::VariableHandle
530 Lang::PathPoint3D::getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const
532 if( strcmp( fieldID, "mid" ) == 0 )
534 return Kernel::VariableHandle( new Kernel::Variable( mid_ ) );
536 if( strcmp( fieldID, "rear" ) == 0 )
538 return Kernel::VariableHandle( new Kernel::Variable( rear_ ) );
540 if( strcmp( fieldID, "front" ) == 0 )
542 return Kernel::VariableHandle( new Kernel::Variable( front_ ) );
544 throw Exceptions::NonExistentMember( getTypeName( ), fieldID );
547 void
548 Lang::PathPoint3D::elementaryJob( Lang::ElementaryPath3D * pth, Concrete::Coords3D * basePoint ) const
550 Concrete::Coords3D * newMid = new Concrete::Coords3D( *basePoint, *mid_ );
551 *basePoint = *newMid;
552 Concrete::PathPoint3D * newPoint = new Concrete::PathPoint3D( newMid );
554 if( rear_ != NullPtr< const Lang::Coords3D >( ) )
556 newPoint->rear_ = new Concrete::Coords3D( *basePoint, *rear_ );
559 if( front_ != NullPtr< const Lang::Coords3D >( ) )
561 newPoint->front_ = new Concrete::Coords3D( *basePoint, *front_ );
564 pth->push_back( newPoint );
567 RefCountPtr< const Lang::Geometric3D >
568 Lang::PathPoint3D::transformed( const Lang::Transform3D & tf, const RefCountPtr< const Lang::Geometric3D > & self ) const
570 PathPoint3D * res = new Lang::PathPoint3D( RefCountPtr< const Lang::Coords3D >( mid_->transformedPtr( tf ) ) );
572 if( rear_ != NullPtr< const Lang::Coords3D >( ) )
574 res->rear_ = RefCountPtr< const Lang::Coords3D >( rear_->transformedPtr( tf ) );
577 if( front_ != NullPtr< const Lang::Coords3D >( ) )
579 res->front_ = RefCountPtr< const Lang::Coords3D >( front_->transformedPtr( tf ) );
582 return RefCountPtr< const Lang::Geometric3D >( res );
585 RefCountPtr< const Lang::Geometric2D >
586 Lang::PathPoint3D::to2D( const Kernel::PassedDyn & dyn, const RefCountPtr< const Lang::Geometric3D > & self ) const
588 Concrete::Length eyez = dyn->getEyeZ( );
589 PathPoint2D * res = new Lang::PathPoint2D( mid_->make2D( eyez ) );
591 if( rear_ != NullPtr< const Lang::Coords3D >( ) )
593 res->rear_ = rear_->make2D( eyez );
596 if( front_ != NullPtr< const Lang::Coords3D >( ) )
598 res->front_ = front_->make2D( eyez );
601 return RefCountPtr< const Lang::Geometric2D >( res );
604 void
605 Lang::PathPoint3D::gcMark( Kernel::GCMarkedSet & marked )
608 Lang::Coords3D * tmp = const_cast< Lang::Coords3D * >( rear_.getPtr( ) );
609 if( tmp != 0 )
611 tmp->gcMark( marked );
615 const_cast< Lang::Coords3D * >( mid_.getPtr( ) )->gcMark( marked );
618 Lang::Coords3D * tmp = const_cast< Lang::Coords3D * >( front_.getPtr( ) );
619 if( tmp != 0 )
621 tmp->gcMark( marked );
626 RefCountPtr< const Lang::Class > Lang::PathPoint3D::TypeID( new Lang::SystemFinalClass( strrefdup( "PathPoint" ) ) );
627 TYPEINFOIMPL( PathPoint3D );
630 Lang::Path2D::Path2D( )
631 : closed_( false )
634 DISPATCHIMPL( Path2D );
636 Lang::Path2D::~Path2D( )
639 void
640 Lang::Path2D::close( )
642 closed_ = true;
644 bool
645 Lang::Path2D::isClosed( ) const
647 return closed_;
650 RefCountPtr< const Lang::Geometric2D >
651 Lang::Path2D::transformed( const Lang::Transform2D & tf, const RefCountPtr< const Lang::Geometric2D > & self ) const
653 typedef const Lang::Path2D ArgType;
654 RefCountPtr< ArgType > selfTyped = self.down_cast< ArgType >( );
655 if( selfTyped == NullPtr< ArgType >( ) )
657 throw Exceptions::InternalError( strrefdup( "Path2D::to3D: self was of unexpected type." ) );
660 return selfTyped->typed_transformed( tf );
663 RefCountPtr< const Lang::Geometric3D >
664 Lang::Path2D::to3D( const RefCountPtr< const Lang::Geometric2D > & self ) const
666 typedef const Lang::Path2D ArgType;
667 RefCountPtr< ArgType > selfTyped = self.down_cast< ArgType >( );
668 if( selfTyped == NullPtr< ArgType >( ) )
670 throw Exceptions::InternalError( strrefdup( "Path2D::to3D: self was of unexpected type." ) );
673 return selfTyped->typed_to3D( selfTyped );
676 RefCountPtr< const Lang::Class > Lang::Path2D::TypeID( new Lang::SystemFinalClass( strrefdup( "Path" ) ) );
677 TYPEINFOIMPL( Path2D );
680 Lang::CompositePath2D::CompositePath2D( )
681 : elementaryPath_( NullPtr< const ElementaryPath2D >( ) )
684 DISPATCHIMPL( CompositePath2D );
686 Lang::CompositePath2D::~CompositePath2D( )
689 Kernel::VariableHandle
690 Lang::CompositePath2D::getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const
692 computeElementaryPath( );
693 return elementaryPath_->getField( fieldID, elementaryPath_ );
696 RefCountPtr< const Lang::Path2D >
697 Lang::CompositePath2D::typed_transformed( const Lang::Transform2D & tf ) const
699 computeElementaryPath( );
700 return elementaryPath_->typed_transformed( tf );
703 RefCountPtr< const Lang::Path3D >
704 Lang::CompositePath2D::typed_to3D( const RefCountPtr< const Lang::Path2D > & self ) const
706 computeElementaryPath( );
707 return RefCountPtr< const Lang::Path3D >( new Lang::Path2Din3D( elementaryPath_ ) );
710 void
711 Lang::CompositePath2D::writePath( ostream & os ) const
713 computeElementaryPath( );
714 elementaryPath_->writePath( os );
717 RefCountPtr< const Lang::ElementaryPath2D >
718 Lang::CompositePath2D::getElementaryPath( ) const
720 computeElementaryPath( );
721 return elementaryPath_;
724 void
725 Lang::CompositePath2D::show( std::ostream & os ) const
727 os << "Composite subpath" ;
731 Lang::ClosedPath2D::ClosedPath2D( RefCountPtr< const Lang::Path2D > openPath )
732 : openPath_( openPath )
734 close( );
737 Lang::ClosedPath2D::~ClosedPath2D( )
740 DISPATCHIMPL( ClosedPath2D );
742 void
743 Lang::ClosedPath2D::elementaryJob( std::stack< const Lang::Value * > * nodeStack, Lang::ElementaryPath2D * pth, Concrete::Coords2D * basePoint ) const
745 openPath_->elementaryJob( nodeStack, pth, basePoint );
747 * Although this seems incorrect, as the fact that this path is closed will not be respected,
748 * this should not be a problem since it is not allowed to connect closed paths with anything.
752 void
753 Lang::ClosedPath2D::gcMark( Kernel::GCMarkedSet & marked )
755 const_cast< Lang::Path2D * >( openPath_.getPtr( ) )->gcMark( marked );
759 Lang::Connection2D::Connection2D( Kernel::ValueRef rear, Kernel::ValueRef front )
760 : rear_( rear ), front_( front )
763 DISPATCHIMPL( Connection2D );
765 Lang::Connection2D::~Connection2D( )
768 void
769 Lang::Connection2D::elementaryJob( std::stack< const Lang::Value * > * nodeStack, Lang::ElementaryPath2D * pth, Concrete::Coords2D * basePoint ) const
771 nodeStack->push( front_.getPtr( ) );
772 nodeStack->push( rear_.getPtr( ) );
775 void
776 Lang::Connection2D::gcMark( Kernel::GCMarkedSet & marked )
778 const_cast< Lang::Value * >( rear_.getPtr( ) )->gcMark( marked );
779 const_cast< Lang::Value * >( front_.getPtr( ) )->gcMark( marked );
783 Lang::SinglePointPath2D::SinglePointPath2D( Kernel::ValueRef thePoint )
784 : thePoint_( thePoint )
787 DISPATCHIMPL( SinglePointPath2D );
789 Lang::SinglePointPath2D::~SinglePointPath2D( )
792 void
793 Lang::SinglePointPath2D::elementaryJob( std::stack< const Lang::Value * > * nodeStack, Lang::ElementaryPath2D * pth, Concrete::Coords2D * basePoint ) const
795 nodeStack->push( thePoint_.getPtr( ) );
798 void
799 Lang::SinglePointPath2D::gcMark( Kernel::GCMarkedSet & marked )
801 const_cast< Lang::Value * >( thePoint_.getPtr( ) )->gcMark( marked );
805 Lang::HeadedPath2D::HeadedPath2D( Kernel::ValueRef rear, const RefCountPtr< const Lang::ElementaryPath2D > & bodyPath, Kernel::ValueRef front )
806 : bodyPath_( new Lang::HeadedPath2D_helper( bodyPath ) ), rearPathPoint_( NullPtr< const Lang::Value >( ) ), frontPathPoint_( NullPtr< const Lang::Value >( ) )
808 if( bodyPath->isClosed( ) )
810 throw Exceptions::InternalError( strrefdup( "Attempt to create closed but headed path." ) );
812 if( bodyPath->empty( ) )
814 throw Exceptions::InternalError( strrefdup( "Attempt to create empty but headed path." ) );
817 if( bodyPath->size( ) == 1 )
819 Lang::ElementaryPath2D::const_iterator i = bodyPath->begin( );
820 Lang::PathPoint2D * newPoint = new Lang::PathPoint2D( RefCountPtr< const Lang::Coords2D >( new Lang::Coords2D( *( (*i)->mid_ ) ) ) );
821 newPoint->rear_ = rear;
822 newPoint->front_ = front;
823 rearPathPoint_ = Kernel::ValueRef( newPoint );
825 return;
828 // We reach here if there's more than 1 point in bodyPath
831 Lang::ElementaryPath2D::const_reverse_iterator i = bodyPath->rbegin( );
832 Lang::PathPoint2D * newPoint = new Lang::PathPoint2D( RefCountPtr< const Lang::Coords2D >( new Lang::Coords2D( *( (*i)->mid_ ) ) ) );
833 if( (*i)->rear_ != 0 )
835 newPoint->rear_ = RefCountPtr< const Lang::Coords2D >( new Lang::Coords2D( *( (*i)->rear_ ) ) );
837 newPoint->front_ = front;
838 frontPathPoint_ = Kernel::ValueRef( newPoint );
841 Lang::ElementaryPath2D::const_iterator i = bodyPath->begin( );
842 Lang::PathPoint2D * newPoint = new Lang::PathPoint2D( RefCountPtr< const Lang::Coords2D >( new Lang::Coords2D( *( (*i)->mid_ ) ) ) );
843 if( (*i)->front_ != 0 )
845 newPoint->front_ = RefCountPtr< const Lang::Coords2D >( new Lang::Coords2D( *( (*i)->front_ ) ) );
847 newPoint->rear_ = rear;
848 rearPathPoint_ = Kernel::ValueRef( newPoint );
852 DISPATCHIMPL( HeadedPath2D );
854 Lang::HeadedPath2D::~HeadedPath2D( )
857 void
858 Lang::HeadedPath2D::elementaryJob( std::stack< const Lang::Value * > * nodeStack, Lang::ElementaryPath2D * pth, Concrete::Coords2D * basePoint ) const
860 if( frontPathPoint_ == NullPtr< const Lang::Value >( ) )
862 // This means that there was just a single point in bodyPath
864 nodeStack->push( rearPathPoint_.getPtr( ) );
865 return;
867 else
869 nodeStack->push( frontPathPoint_.getPtr( ) );
870 nodeStack->push( bodyPath_.getPtr( ) );
871 nodeStack->push( rearPathPoint_.getPtr( ) );
875 void
876 Lang::HeadedPath2D::gcMark( Kernel::GCMarkedSet & marked )
878 const_cast< Lang::HeadedPath2D_helper * >( bodyPath_.getPtr( ) )->gcMark( marked );
879 const_cast< Lang::Value * >( rearPathPoint_.getPtr( ) )->gcMark( marked );
880 const_cast< Lang::Value * >( frontPathPoint_.getPtr( ) )->gcMark( marked );
884 Lang::HeadedPath2D_helper::HeadedPath2D_helper( const RefCountPtr< const Lang::ElementaryPath2D > & bodyPath )
885 : bodyPath_( bodyPath )
888 Lang::HeadedPath2D_helper::~HeadedPath2D_helper( )
891 void
892 Lang::HeadedPath2D_helper::elementaryJob( std::stack< const Lang::Value * > * nodeStack, Lang::ElementaryPath2D * pth, Concrete::Coords2D * basePoint ) const
894 if( bodyPath_->size( ) <= 1 )
896 throw Exceptions::InternalError( strrefdup( "HeadedPath2D_helper::elementaryJob was unexpectedly called with a short path." ) );
899 Lang::ElementaryPath2D::const_iterator i = bodyPath_->begin( );
900 ++i;
901 Lang::ElementaryPath2D::const_iterator end = bodyPath_->end( );
902 --end;
903 for( ; i != end; ++i )
905 pth->push_back( new Concrete::PathPoint2D( **i ) );
908 --i; /* Go back to the last point added to pth. */
909 *basePoint = *((*i)->mid_);
912 void
913 Lang::HeadedPath2D_helper::gcMark( Kernel::GCMarkedSet & marked )
915 const_cast< Lang::ElementaryPath2D * >( bodyPath_.getPtr( ) )->gcMark( marked );
920 Lang::MultiPath2D::MultiPath2D( )
923 DISPATCHIMPL( MultiPath2D );
925 Lang::MultiPath2D::~MultiPath2D( )
928 Lang::MultiPath2D *
929 Lang::MultiPath2D::clone( ) const
931 Lang::MultiPath2D * res = new Lang::MultiPath2D( );
932 for( const_iterator i = begin( ); i != end( ); ++i )
934 res->push_back( *i );
936 return res;
939 RefCountPtr< const Lang::Class > Lang::MultiPath2D::TypeID( new Lang::SystemFinalClass( strrefdup( "MultiPath" ) ) );
940 TYPEINFOIMPL( MultiPath2D );
942 void
943 Lang::MultiPath2D::show( std::ostream & os ) const
945 os << "Path with " << size( ) << " subpaths" ;
948 Kernel::VariableHandle
949 Lang::MultiPath2D::getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const
951 if( strcmp( fieldID, "list" ) == 0 )
953 RefCountPtr< const Lang::SingleList > res = Lang::THE_CONS_NULL;
954 for( const_reverse_iterator i = rbegin( ); i != rend( ); ++i )
956 res = RefCountPtr< const Lang::SingleList >( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( *i ) ),
957 res ) );
959 return Kernel::VariableHandle( new Kernel::Variable( res ) );
961 throw Exceptions::NonExistentMember( getTypeName( ), fieldID );
964 RefCountPtr< const Lang::Geometric2D >
965 Lang::MultiPath2D::transformed( const Lang::Transform2D & tf, const RefCountPtr< const Lang::Geometric2D > & self ) const
967 Lang::MultiPath2D * res = new Lang::MultiPath2D( );
968 for( const_iterator i = begin( ); i != end( ); ++i )
970 res->push_back( (*i)->typed_transformed( tf ) );
972 return RefCountPtr< Lang::Geometric2D >( res );
975 RefCountPtr< const Lang::Geometric3D >
976 Lang::MultiPath2D::to3D( const RefCountPtr< const Lang::Geometric2D > & self ) const
978 Lang::MultiPath3D * res = new Lang::MultiPath3D( );
979 for( const_iterator i = begin( ); i != end( ); ++i )
981 res->push_back( (*i)->typed_to3D( *i ) );
983 return RefCountPtr< const Lang::Geometric3D >( res );
986 void
987 Lang::MultiPath2D::writePath( ostream & os ) const
989 for( const_iterator i = begin( ); i != end( ); ++i )
991 (*i)->writePath( os );
995 void
996 Lang::MultiPath2D::gcMark( Kernel::GCMarkedSet & marked )
998 for( const_iterator i = begin( ); i != end( ); ++i )
1000 const_cast< Path2D * >( i->getPtr( ) )->gcMark( marked );
1005 Lang::MultiPath3D::MultiPath3D( )
1008 DISPATCHIMPL( MultiPath3D );
1010 Lang::MultiPath3D::~MultiPath3D( )
1013 Lang::MultiPath3D *
1014 Lang::MultiPath3D::clone( ) const
1016 Lang::MultiPath3D * res = new Lang::MultiPath3D( );
1017 for( const_iterator i = begin( ); i != end( ); ++i )
1019 res->push_back( *i );
1021 return res;
1024 RefCountPtr< const Lang::Class > Lang::MultiPath3D::TypeID( new Lang::SystemFinalClass( strrefdup( "MultiPath3D" ) ) );
1025 TYPEINFOIMPL( MultiPath3D );
1027 void
1028 Lang::MultiPath3D::show( std::ostream & os ) const
1030 os << "3D path with " << size( ) << " subpaths" ;
1033 Kernel::VariableHandle
1034 Lang::MultiPath3D::getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const
1036 if( strcmp( fieldID, "list" ) == 0 )
1038 RefCountPtr< const Lang::SingleList > res = Lang::THE_CONS_NULL;
1039 for( const_reverse_iterator i = rbegin( ); i != rend( ); ++i )
1041 res = RefCountPtr< const Lang::SingleList >( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( *i ) ),
1042 res ) );
1044 return Kernel::VariableHandle( new Kernel::Variable( res ) );
1046 throw Exceptions::NonExistentMember( getTypeName( ), fieldID );
1049 RefCountPtr< const Lang::Geometric3D >
1050 Lang::MultiPath3D::transformed( const Lang::Transform3D & tf, const RefCountPtr< const Lang::Geometric3D > & self ) const
1052 Lang::MultiPath3D * res = new Lang::MultiPath3D( );
1053 for( const_iterator i = begin( ); i != end( ); ++i )
1055 res->push_back( (*i)->typed_transformed( tf ) );
1057 return RefCountPtr< Lang::Geometric3D >( res );
1060 RefCountPtr< const Lang::Geometric2D >
1061 Lang::MultiPath3D::to2D( const Kernel::PassedDyn & dyn, const RefCountPtr< const Lang::Geometric3D > & self ) const
1063 Concrete::Length eyez = dyn->getEyeZ( );
1064 Lang::MultiPath2D * res = new Lang::MultiPath2D( );
1065 for( const_iterator i = begin( ); i != end( ); ++i )
1067 res->push_back( (*i)->make2D( eyez ) );
1069 return RefCountPtr< const Lang::Geometric2D >( res );
1072 void
1073 Lang::MultiPath3D::gcMark( Kernel::GCMarkedSet & marked )
1075 for( const_iterator i = begin( ); i != end( ); ++i )
1077 const_cast< Path3D * >( i->getPtr( ) )->gcMark( marked );
1082 Lang::Path3D::Path3D( )
1083 : closed_( false )
1086 DISPATCHIMPL( Path3D );
1088 Lang::Path3D::~Path3D( )
1091 void
1092 Lang::Path3D::close( )
1094 closed_ = true;
1096 bool
1097 Lang::Path3D::isClosed( ) const
1099 return closed_;
1102 RefCountPtr< const Lang::Geometric3D >
1103 Lang::Path3D::transformed( const Lang::Transform3D & tf, const RefCountPtr< const Lang::Geometric3D > & self ) const
1105 typedef const Lang::Path3D ArgType;
1106 RefCountPtr< ArgType > selfTyped = self.down_cast< ArgType >( );
1107 if( selfTyped == NullPtr< ArgType >( ) )
1109 throw Exceptions::InternalError( strrefdup( "Path3D::to3D: self was of unexpected type." ) );
1112 return selfTyped->typed_transformed( tf );
1115 RefCountPtr< const Lang::Geometric2D >
1116 Lang::Path3D::to2D( const Kernel::PassedDyn & dyn, const RefCountPtr< const Lang::Geometric3D > & self ) const
1118 Concrete::Length eyez = dyn->getEyeZ( );
1119 return this->make2D( eyez );
1122 RefCountPtr< const Lang::Class > Lang::Path3D::TypeID( new Lang::SystemFinalClass( strrefdup( "Path3D" ) ) );
1123 TYPEINFOIMPL( Path3D );
1126 Lang::Path2Din3D::Path2Din3D( const RefCountPtr< const Lang::ElementaryPath2D > & elementaryPath2D )
1127 : elementaryPath2D_( elementaryPath2D )
1129 if( elementaryPath2D_->isClosed( ) )
1131 close( );
1135 Lang::Path2Din3D::~Path2Din3D( )
1138 RefCountPtr< const Lang::ElementaryPath2D >
1139 Lang::Path2Din3D::make2D( Concrete::Length eyez ) const
1141 // Since this path has not been transformed, it's "already" in 2D.
1143 return elementaryPath2D_;
1146 RefCountPtr< const Lang::Path3D >
1147 Lang::Path2Din3D::typed_transformed( const Lang::Transform3D & tf ) const
1149 return elementaryPath2D_->elementaryTransformed( tf );
1152 void
1153 Lang::Path2Din3D::elementaryJob( std::stack< const Lang::Path3D * > * nodeStack, Lang::ElementaryPath3D * pth, Concrete::Coords3D * basePoint ) const
1155 for( Lang::ElementaryPath2D::const_iterator i = elementaryPath2D_->begin( ); i != elementaryPath2D_->end( ); ++i )
1157 pth->push_back( (*i)->typed_to3D( ) );
1159 *basePoint = *(elementaryPath2D_->back( )->mid_);
1162 void
1163 Lang::Path2Din3D::gcMark( Kernel::GCMarkedSet & marked )
1165 const_cast< Lang::ElementaryPath2D * >( elementaryPath2D_.getPtr( ) )->gcMark( marked );
1170 Lang::ClosedPath3D::ClosedPath3D( RefCountPtr< const Lang::Path3D > openPath )
1171 : openPath_( openPath )
1173 close( );
1176 Lang::ClosedPath3D::~ClosedPath3D( )
1179 DISPATCHIMPL( ClosedPath3D );
1181 void
1182 Lang::ClosedPath3D::elementaryJob( std::stack< const Lang::Path3D * > * nodeStack, Lang::ElementaryPath3D * pth, Concrete::Coords3D * basePoint ) const
1184 openPath_->elementaryJob( nodeStack, pth, basePoint );
1186 * Although this seems incorrect, as the fact that this path is closed will not be respected,
1187 * this should not be a problem since it is not allowed to connect closed paths with anything.
1191 void
1192 Lang::ClosedPath3D::gcMark( Kernel::GCMarkedSet & marked )
1194 const_cast< Lang::Path3D * >( openPath_.getPtr( ) )->gcMark( marked );
1198 Lang::Connection3D::Connection3D( const RefCountPtr< const Lang::Path3D > & rear, const RefCountPtr< const Lang::Path3D > & front )
1199 : rear_( rear ), front_( front )
1202 Lang::Connection3D::~Connection3D( )
1205 void
1206 Lang::Connection3D::elementaryJob( std::stack< const Lang::Path3D * > * nodeStack, Lang::ElementaryPath3D * pth, Concrete::Coords3D * basePoint ) const
1208 nodeStack->push( front_.getPtr( ) );
1209 nodeStack->push( rear_.getPtr( ) );
1212 void
1213 Lang::Connection3D::gcMark( Kernel::GCMarkedSet & marked )
1215 const_cast< Lang::Path3D * >( rear_.getPtr( ) )->gcMark( marked );
1216 const_cast< Lang::Path3D * >( front_.getPtr( ) )->gcMark( marked );
1219 DISPATCHIMPL( Connection3D );
1222 Lang::SinglePointPath3D::SinglePointPath3D( const RefCountPtr< const Lang::PathPoint3D > & thePoint )
1223 : thePoint_( thePoint )
1226 Lang::SinglePointPath3D::SinglePointPath3D( const RefCountPtr< const Lang::Coords3D > & mid )
1227 : thePoint_( new Lang::PathPoint3D( mid ) )
1230 DISPATCHIMPL( SinglePointPath3D );
1232 Lang::SinglePointPath3D::~SinglePointPath3D( )
1235 void
1236 Lang::SinglePointPath3D::elementaryJob( std::stack< const Lang::Path3D * > * nodeStack, Lang::ElementaryPath3D * pth, Concrete::Coords3D * basePoint ) const
1238 thePoint_->elementaryJob( pth, basePoint );
1241 void
1242 Lang::SinglePointPath3D::gcMark( Kernel::GCMarkedSet & marked )
1244 const_cast< Lang::PathPoint3D * >( thePoint_.getPtr( ) )->gcMark( marked );
1248 Lang::CompositePath3D::CompositePath3D( )
1249 : elementaryPath_( NullPtr< const ElementaryPath3D >( ) )
1252 DISPATCHIMPL( CompositePath3D );
1254 Lang::CompositePath3D::~CompositePath3D( )
1257 Kernel::VariableHandle
1258 Lang::CompositePath3D::getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const
1260 computeElementaryPath( );
1261 return elementaryPath_->getField( fieldID, elementaryPath_ );
1264 RefCountPtr< const Lang::Path3D >
1265 Lang::CompositePath3D::typed_transformed( const Lang::Transform3D & tf ) const
1267 computeElementaryPath( );
1268 return elementaryPath_->typed_transformed( tf );
1271 RefCountPtr< const Lang::ElementaryPath2D >
1272 Lang::CompositePath3D::make2D( Concrete::Length eyez ) const
1274 computeElementaryPath( );
1275 return elementaryPath_->make2D( eyez );
1278 RefCountPtr< const Lang::ElementaryPath3D >
1279 Lang::CompositePath3D::getElementaryPath( ) const
1281 computeElementaryPath( );
1283 return elementaryPath_;
1286 void
1287 Lang::CompositePath3D::show( std::ostream & os ) const
1289 os << "Composite subpath in 3D" ;
1292 void
1293 Lang::CompositePath3D::computeElementaryPath( ) const
1295 if( elementaryPath_ != NullPtr< const Lang::ElementaryPath3D >( ) )
1297 return;
1299 Lang::ElementaryPath3D * pth = new Lang::ElementaryPath3D;
1301 Concrete::Coords3D basePoint( 0, 0, 0 );
1303 std::stack< const Lang::Path3D * > nodeStack;
1304 nodeStack.push( this );
1305 while( ! nodeStack.empty( ) )
1307 const Lang::Path3D * node = nodeStack.top( );
1308 nodeStack.pop( );
1309 node->elementaryJob( & nodeStack, pth, & basePoint );
1312 if( closed_ )
1314 pth->close( );
1317 elementaryPath_ = RefCountPtr< const Lang::ElementaryPath3D >( pth );
1321 Lang::HeadedPath3D::HeadedPath3D( Kernel::ValueRef rear, const RefCountPtr< const Lang::ElementaryPath3D > & bodyPath, Kernel::ValueRef front )
1322 : bodyPath_( new Lang::HeadedPath3D_helper( bodyPath ) ),
1323 rearPathPoint_( NullPtr< const Lang::SinglePointPath3D >( ) ),
1324 frontPathPoint_( NullPtr< const Lang::SinglePointPath3D >( ) )
1326 if( bodyPath->isClosed( ) )
1328 throw Exceptions::InternalError( strrefdup( "Attempt to create closed but headed path." ) );
1330 if( bodyPath->empty( ) )
1332 throw Exceptions::InternalError( strrefdup( "Attempt to create empty but headed path." ) );
1334 if( bodyPath->size( ) == 1 )
1336 Lang::ElementaryPath3D::const_iterator i = bodyPath->begin( );
1337 Lang::PathPoint3D * newPoint = new Lang::PathPoint3D( RefCountPtr< const Lang::Coords3D >( new Lang::Coords3D( *( (*i)->mid_ ) ) ) );
1338 newPoint->rear_ = rear;
1339 newPoint->front_ = front;
1340 rearPathPoint_ = RefCountPtr< const Lang::SinglePointPath3D >( new Lang::SinglePointPath3D( RefCountPtr< const Lang::PathPoint3D >( newPoint ) ) );
1342 return;
1345 // We reach here if there's more than one point in the body.
1348 Lang::ElementaryPath3D::const_reverse_iterator i = bodyPath->rbegin( );
1349 Lang::PathPoint3D * newPoint = new Lang::PathPoint3D( RefCountPtr< const Lang::Coords3D >( new Lang::Coords3D( *( (*i)->mid_ ) ) ) );
1350 if( (*i)->rear_ != 0 )
1352 newPoint->rear_ = RefCountPtr< const Lang::Coords3D >( new Lang::Coords3D( *( (*i)->rear_ ) ) );
1354 newPoint->front_ = front;
1355 frontPathPoint_ = RefCountPtr< const Lang::SinglePointPath3D >( new Lang::SinglePointPath3D( RefCountPtr< const Lang::PathPoint3D >( newPoint ) ) );
1358 Lang::ElementaryPath3D::const_iterator i = bodyPath->begin( );
1359 Lang::PathPoint3D * newPoint = new Lang::PathPoint3D( RefCountPtr< const Lang::Coords3D >( new Lang::Coords3D( *( (*i)->mid_ ) ) ) );
1360 if( (*i)->front_ != 0 )
1362 newPoint->front_ = RefCountPtr< const Lang::Coords3D >( new Lang::Coords3D( *( (*i)->front_ ) ) );
1364 newPoint->rear_ = rear;
1365 rearPathPoint_ = RefCountPtr< const Lang::SinglePointPath3D >( new Lang::SinglePointPath3D( RefCountPtr< const Lang::PathPoint3D >( newPoint ) ) );
1370 DISPATCHIMPL( HeadedPath3D );
1372 Lang::HeadedPath3D::~HeadedPath3D( )
1375 void
1376 Lang::HeadedPath3D::elementaryJob( std::stack< const Lang::Path3D * > * nodeStack, Lang::ElementaryPath3D * pth, Concrete::Coords3D * basePoint ) const
1378 if( frontPathPoint_ == NullPtr< const Lang::SinglePointPath3D >( ) )
1380 // This means that there was just a single point in bodyPath
1382 nodeStack->push( rearPathPoint_.getPtr( ) );
1383 return;
1385 else
1387 nodeStack->push( frontPathPoint_.getPtr( ) );
1388 nodeStack->push( bodyPath_.getPtr( ) );
1389 nodeStack->push( rearPathPoint_.getPtr( ) );
1393 void
1394 Lang::HeadedPath3D::gcMark( Kernel::GCMarkedSet & marked )
1396 const_cast< Lang::HeadedPath3D_helper * >( bodyPath_.getPtr( ) )->gcMark( marked );
1397 const_cast< Lang::SinglePointPath3D * >( rearPathPoint_.getPtr( ) )->gcMark( marked );
1398 const_cast< Lang::SinglePointPath3D * >( frontPathPoint_.getPtr( ) )->gcMark( marked );
1402 Lang::HeadedPath3D_helper::HeadedPath3D_helper( const RefCountPtr< const Lang::ElementaryPath3D > & bodyPath )
1403 : bodyPath_( bodyPath )
1406 Lang::HeadedPath3D_helper::~HeadedPath3D_helper( )
1409 void
1410 Lang::HeadedPath3D_helper::elementaryJob( std::stack< const Lang::Path3D * > * nodeStack, Lang::ElementaryPath3D * pth, Concrete::Coords3D * basePoint ) const
1412 if( bodyPath_->size( ) <= 1 )
1414 throw Exceptions::InternalError( strrefdup( "HeadedPath3D_helper::elementaryJob was unexpectedly called with a short path." ) );
1417 Lang::ElementaryPath3D::const_iterator i = bodyPath_->begin( );
1418 ++i;
1419 Lang::ElementaryPath3D::const_iterator end = bodyPath_->end( );
1420 --end;
1421 for( ; i != end; ++i )
1423 pth->push_back( new Concrete::PathPoint3D( **i ) );
1426 --i; /* Go back to the last point added to pth. */
1427 *basePoint = *((*i)->mid_);
1430 void
1431 Lang::HeadedPath3D_helper::gcMark( Kernel::GCMarkedSet & marked )
1433 const_cast< Lang::ElementaryPath3D * >( bodyPath_.getPtr( ) )->gcMark( marked );