1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008, 2009 Henrik Tidefelt
21 #include "shapestypes.h"
22 #include "shapesexceptions.h"
26 #include "angleselect.h"
29 #include "continuations.h"
30 #include "dynamicenvironment.h"
36 using namespace Shapes
;
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
;
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( )
71 Kernel::PolarHandlePromise::~PolarHandlePromise( )
75 Kernel::PolarHandleEmptyPromise::PolarHandleEmptyPromise( )
78 Kernel::PolarHandleEmptyPromise::~PolarHandleEmptyPromise( )
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
) );
90 Kernel::PolarHandleEmptyPromise::gcMark( Kernel::GCMarkedSet
& marked
) const
96 Kernel::PolarHandleEmptyPromise::show( std::ostream
& os
) const
98 os
<< "< undefined >" ;
102 Kernel::PolarHandleTruePromise::PolarHandleTruePromise( Kernel::Thunk
* thunk
)
106 Kernel::PolarHandleTruePromise::~PolarHandleTruePromise( )
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.
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
) );
137 evalState
.expr_
->eval( & evalState
);
140 typedef const Lang::Length ArgType
;
141 ArgType
* valPtr
= dynamic_cast< ArgType
* >( valUntyped
.getPtr( ) );
144 throw Exceptions::TypeMismatch( thunk_
->getExpr( )->loc( ), valUntyped
->getTypeName( ), ArgType::staticTypeName( ) );
147 return valPtr
->getScalar( );
151 Kernel::PolarHandleTruePromise::gcMark( Kernel::GCMarkedSet
& marked
) const
155 thunk_
->gcMark( marked
);
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( )
188 Lang::PolarHandle2D::show( std::ostream
& os
) const
190 os
<< "Completely specified" ;
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( )
210 Lang::PolarHandle2DFree_a::show( std::ostream
& os
) const
212 os
<< "Free angle, promise pointer: " << rPromise_
.getPtr( ) ;
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( )
232 Lang::PolarHandle2DFree_r::show( std::ostream
& os
) const
234 os
<< "Free modulus, angle = " << a_
;
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( )
254 Lang::PolarHandle2DFree_ra::show( std::ostream
& os
) const
256 os
<< "Completely free" ;
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_
);
283 if( orig
.front_
!= orig
.mid_
)
285 front_
= new Concrete::Coords2D( *orig
.front_
);
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
>( ) ),
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
>( ) ),
307 rear_( new Concrete::Coords2D( midx
, midy
) ), mid_( rear_
), front_( rear_
)
310 Concrete::PathPoint2D::~PathPoint2D( )
312 if( rear_
!= 0 && rear_
!= mid_
)
320 if( front_
!= 0 && front_
!= mid_
)
326 Concrete::PathPoint2D
*
327 Concrete::PathPoint2D::transformed( const Lang::Transform2D
& tf
) const
329 Concrete::PathPoint2D
* res
= new Concrete::PathPoint2D( mid_
->transformedPtr( tf
) );
332 res
->rear_
= rear_
->transformedPtr( tf
);
336 res
->front_
= front_
->transformedPtr( tf
);
341 Concrete::PathPoint3D
*
342 Concrete::PathPoint2D::transformed( const Lang::Transform3D
& tf
) const
344 Concrete::PathPoint3D
* res
= new Concrete::PathPoint3D( mid_
->transformedPtr( tf
) );
347 res
->rear_
= rear_
->transformedPtr( tf
);
351 res
->front_
= front_
->transformedPtr( tf
);
356 Concrete::PathPoint3D
*
357 Concrete::PathPoint2D::typed_to3D( ) const
359 Concrete::PathPoint3D
* res
= new Concrete::PathPoint3D( *mid_
);
362 res
->rear_
= new Concrete::Coords3D( *rear_
);
366 res
->front_
= new Concrete::Coords3D( *front_
);
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_
);
384 if( orig
.front_
!= orig
.mid_
)
386 front_
= new Concrete::Coords3D( *orig
.front_
);
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_
)
416 if( front_
!= 0 && front_
!= mid_
)
422 Concrete::PathPoint3D
*
423 Concrete::PathPoint3D::transformed( const Lang::Transform3D
& tf
) const
425 Concrete::PathPoint3D
* res
= new Concrete::PathPoint3D( mid_
->transformedPtr( tf
) );
428 res
->rear_
= rear_
->transformedPtr( tf
);
432 res
->front_
= front_
->transformedPtr( tf
);
437 Concrete::PathPoint2D
*
438 Concrete::PathPoint3D::make2D( Concrete::Length eyez
) const
440 Concrete::PathPoint2D
* res
= new Concrete::PathPoint2D( mid_
->make2D( eyez
) );
443 res
->rear_
= rear_
->make2D( eyez
);
447 res
->front_
= front_
->make2D( eyez
);
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." ) );
493 Lang::PathPoint2D::gcMark( Kernel::GCMarkedSet
& marked
)
496 Lang::Value
* tmp
= const_cast< Lang::Value
* >( rear_
.getPtr( ) );
499 tmp
->gcMark( marked
);
503 const_cast< Lang::Coords2D
* >( mid_
.getPtr( ) )->gcMark( marked
);
506 Lang::Value
* tmp
= const_cast< Lang::Value
* >( front_
.getPtr( ) );
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
);
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
);
605 Lang::PathPoint3D::gcMark( Kernel::GCMarkedSet
& marked
)
608 Lang::Coords3D
* tmp
= const_cast< Lang::Coords3D
* >( rear_
.getPtr( ) );
611 tmp
->gcMark( marked
);
615 const_cast< Lang::Coords3D
* >( mid_
.getPtr( ) )->gcMark( marked
);
618 Lang::Coords3D
* tmp
= const_cast< Lang::Coords3D
* >( front_
.getPtr( ) );
621 tmp
->gcMark( marked
);
626 RefCountPtr
< const Lang::Class
> Lang::PathPoint3D::TypeID( new Lang::SystemFinalClass( strrefdup( "PathPoint" ) ) );
627 TYPEINFOIMPL( PathPoint3D
);
630 Lang::Path2D::Path2D( )
634 DISPATCHIMPL( Path2D
);
636 Lang::Path2D::~Path2D( )
640 Lang::Path2D::close( )
645 Lang::Path2D::isClosed( ) const
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_
) );
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_
;
725 Lang::CompositePath2D::show( std::ostream
& os
) const
727 os
<< "Composite subpath" ;
731 Lang::ClosedPath2D::ClosedPath2D( RefCountPtr
< const Lang::Path2D
> openPath
)
732 : openPath_( openPath
)
737 Lang::ClosedPath2D::~ClosedPath2D( )
740 DISPATCHIMPL( ClosedPath2D
);
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.
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( )
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( ) );
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( )
793 Lang::SinglePointPath2D::elementaryJob( std::stack
< const Lang::Value
* > * nodeStack
, Lang::ElementaryPath2D
* pth
, Concrete::Coords2D
* basePoint
) const
795 nodeStack
->push( thePoint_
.getPtr( ) );
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
);
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( )
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( ) );
869 nodeStack
->push( frontPathPoint_
.getPtr( ) );
870 nodeStack
->push( bodyPath_
.getPtr( ) );
871 nodeStack
->push( rearPathPoint_
.getPtr( ) );
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( )
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( );
901 Lang::ElementaryPath2D::const_iterator end
= bodyPath_
->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_
);
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( )
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
);
939 RefCountPtr
< const Lang::Class
> Lang::MultiPath2D::TypeID( new Lang::SystemFinalClass( strrefdup( "MultiPath" ) ) );
940 TYPEINFOIMPL( MultiPath2D
);
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
) ),
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
);
987 Lang::MultiPath2D::writePath( ostream
& os
) const
989 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
991 (*i
)->writePath( os
);
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( )
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
);
1024 RefCountPtr
< const Lang::Class
> Lang::MultiPath3D::TypeID( new Lang::SystemFinalClass( strrefdup( "MultiPath3D" ) ) );
1025 TYPEINFOIMPL( MultiPath3D
);
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
) ),
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
);
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( )
1086 DISPATCHIMPL( Path3D
);
1088 Lang::Path3D::~Path3D( )
1092 Lang::Path3D::close( )
1097 Lang::Path3D::isClosed( ) const
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( ) )
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
);
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_
);
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
)
1176 Lang::ClosedPath3D::~ClosedPath3D( )
1179 DISPATCHIMPL( ClosedPath3D
);
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.
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( )
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( ) );
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( )
1236 Lang::SinglePointPath3D::elementaryJob( std::stack
< const Lang::Path3D
* > * nodeStack
, Lang::ElementaryPath3D
* pth
, Concrete::Coords3D
* basePoint
) const
1238 thePoint_
->elementaryJob( pth
, basePoint
);
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_
;
1287 Lang::CompositePath3D::show( std::ostream
& os
) const
1289 os
<< "Composite subpath in 3D" ;
1293 Lang::CompositePath3D::computeElementaryPath( ) const
1295 if( elementaryPath_
!= NullPtr
< const Lang::ElementaryPath3D
>( ) )
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( );
1309 node
->elementaryJob( & nodeStack
, pth
, & basePoint
);
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
) ) );
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( )
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( ) );
1387 nodeStack
->push( frontPathPoint_
.getPtr( ) );
1388 nodeStack
->push( bodyPath_
.getPtr( ) );
1389 nodeStack
->push( rearPathPoint_
.getPtr( ) );
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( )
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( );
1419 Lang::ElementaryPath3D::const_iterator end
= bodyPath_
->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_
);
1431 Lang::HeadedPath3D_helper::gcMark( Kernel::GCMarkedSet
& marked
)
1433 const_cast< Lang::ElementaryPath3D
* >( bodyPath_
.getPtr( ) )->gcMark( marked
);