1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008, 2009, 2014 Henrik Tidefelt
21 #include "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 " ;
86 Lang::DYNAMIC_VARIABLE_ID_DEFAULT_UNIT
.show( msg
, Ast::Identifier::DYNAMIC_VARIABLE
);
88 throw Exceptions::MiscellaneousRequirement( strrefdup( msg
) );
92 Kernel::PolarHandleEmptyPromise::gcMark( Kernel::GCMarkedSet
& marked
) const
98 Kernel::PolarHandleEmptyPromise::show( std::ostream
& os
) const
100 os
<< "< undefined >" ;
104 Kernel::PolarHandleTruePromise::PolarHandleTruePromise( Kernel::Thunk
* thunk
)
108 Kernel::PolarHandleTruePromise::~PolarHandleTruePromise( )
115 Kernel::PolarHandleTruePromise::force( const Concrete::PathPoint2D
* specialUnitP0
, const Concrete::PathPoint2D
* specialUnitP1
, bool reverse
) const
117 Kernel::ValueRef valUntyped
= NullPtr
< const Lang::Value
>( );
119 /* Note that the use of a StoreValueContinuation relies on valUntyped being alive at the time the continuation is invoked.
122 Kernel::EvalState
evalState( 0,
124 NullPtr
< Kernel::DynamicEnvironment
>( ),
125 Kernel::ContRef( new Kernel::StoreValueContinuation( & valUntyped
,
126 Kernel::ContRef( new Kernel::ExitContinuation( & done
, thunk_
->getExpr( )->loc( ) ) ),
127 thunk_
->getExpr( )->loc( ) ) ) );
129 thunk_
->force( & evalState
, false ); /* note that the dynamic environment is set below, before evaluation begins. "false" means that the thunk may be forced repeatedly */
131 Kernel::SpecialUnitVariables
* dynVars
= new Kernel::SpecialUnitVariables
;
132 dynVars
->reverseDirection_
= reverse
;
133 dynVars
->p0_
= specialUnitP0
;
134 dynVars
->p1_
= specialUnitP1
;
135 evalState
.dyn_
= Kernel::PassedDyn( new Kernel::DynamicEnvironment( evalState
.dyn_
, dynVars
) );
139 evalState
.expr_
->eval( & evalState
);
142 typedef const Lang::Length ArgType
;
143 ArgType
* valPtr
= dynamic_cast< ArgType
* >( valUntyped
.getPtr( ) );
146 throw Exceptions::TypeMismatch( thunk_
->getExpr( )->loc( ), valUntyped
->getTypeName( ), ArgType::staticTypeName( ) );
149 return valPtr
->getScalar( );
153 Kernel::PolarHandleTruePromise::gcMark( Kernel::GCMarkedSet
& marked
) const
157 thunk_
->gcMark( marked
);
162 Kernel::PolarHandleTruePromise::show( std::ostream
& os
) const
164 os
<< "Dynamic expression at " << thunk_
->getExpr( )->loc( ) ;
168 Lang::PolarHandleBase::PolarHandleBase( )
171 DISPATCHIMPL( PolarHandleBase
);
173 Lang::PolarHandleBase::~PolarHandleBase( )
176 RefCountPtr
< const Lang::Class
> Lang::PolarHandleBase::TypeID( new Lang::SystemFinalClass( strrefdup( "PolarHandle" ) ) );
177 TYPEINFOIMPL( PolarHandleBase
);
180 Lang::PolarHandle2D::PolarHandle2D( const RefCountPtr
< const Kernel::PolarHandlePromise
> & rPromise
, double a
)
181 : rPromise_( rPromise
), a_( a
)
184 DISPATCHIMPL( PolarHandle2D
);
186 Lang::PolarHandle2D::~PolarHandle2D( )
190 Lang::PolarHandle2D::show( std::ostream
& os
) const
192 os
<< "Completely specified" ;
196 Lang::PolarHandle2D::gcMark( Kernel::GCMarkedSet
& marked
)
198 rPromise_
->gcMark( marked
);
202 Lang::PolarHandle2DFree_a::PolarHandle2DFree_a( const RefCountPtr
< const Kernel::PolarHandlePromise
> & rPromise
)
203 : rPromise_( rPromise
)
206 DISPATCHIMPL( PolarHandle2DFree_a
);
208 Lang::PolarHandle2DFree_a::~PolarHandle2DFree_a( )
212 Lang::PolarHandle2DFree_a::show( std::ostream
& os
) const
214 os
<< "Free angle, promise pointer: " << rPromise_
.getPtr( ) ;
218 Lang::PolarHandle2DFree_a::gcMark( Kernel::GCMarkedSet
& marked
)
220 rPromise_
->gcMark( marked
);
224 Lang::PolarHandle2DFree_r::PolarHandle2DFree_r( const RefCountPtr
< const Kernel::PolarHandlePromise
> & defaultModulus
, double a
)
225 : defaultModulus_( defaultModulus
), a_( a
)
228 DISPATCHIMPL( PolarHandle2DFree_r
);
230 Lang::PolarHandle2DFree_r::~PolarHandle2DFree_r( )
234 Lang::PolarHandle2DFree_r::show( std::ostream
& os
) const
236 os
<< "Free modulus, angle = " << a_
;
240 Lang::PolarHandle2DFree_r::gcMark( Kernel::GCMarkedSet
& marked
)
242 defaultModulus_
->gcMark( marked
);
246 Lang::PolarHandle2DFree_ra::PolarHandle2DFree_ra( const RefCountPtr
< const Kernel::PolarHandlePromise
> & defaultModulus
)
247 : defaultModulus_( defaultModulus
)
250 DISPATCHIMPL( PolarHandle2DFree_ra
);
252 Lang::PolarHandle2DFree_ra::~PolarHandle2DFree_ra( )
256 Lang::PolarHandle2DFree_ra::show( std::ostream
& os
) const
258 os
<< "Completely free" ;
262 Lang::PolarHandle2DFree_ra::gcMark( Kernel::GCMarkedSet
& marked
)
264 defaultModulus_
->gcMark( marked
);
268 Concrete::PathPoint2D::PathPoint2D( const Concrete::PathPoint2D
& orig
)
269 : rearState_( orig
.rearState_
), rearAngle_( orig
.rearAngle_
), rearModulus_( orig
.rearModulus_
),
270 rearModulusPromise_( NullPtr
< Kernel::PolarHandlePromise
>( ) ),
271 frontState_( orig
.frontState_
), frontAngle_( orig
.frontAngle_
), frontModulus_( orig
.frontModulus_
),
272 frontModulusPromise_( NullPtr
< Kernel::PolarHandlePromise
>( ) ),
273 defaultAngle_( orig
.defaultAngle_
)
275 mid_
= new Concrete::Coords2D( *orig
.mid_
);
277 if( orig
.rear_
!= orig
.mid_
)
279 rear_
= new Concrete::Coords2D( *orig
.rear_
);
285 if( orig
.front_
!= orig
.mid_
)
287 front_
= new Concrete::Coords2D( *orig
.front_
);
295 /* The initial state is set to COMPLETE, even though theoretically, the angle towards the neighboring pathpoints should be computed.
296 * However, by setting the default rearAngle_ and frontAngle_ to NaN, we can replace an atan2 computation by an IS_NAN test.
298 Concrete::PathPoint2D::PathPoint2D( Concrete::Coords2D
* mid
)
299 : rearState_( COMPLETE
), rearAngle_( std::numeric_limits
< double >::signaling_NaN( ) ), rearModulusPromise_( NullPtr
< Kernel::PolarHandlePromise
>( ) ),
300 frontState_( COMPLETE
), frontAngle_( std::numeric_limits
< double >::signaling_NaN( ) ), frontModulusPromise_( NullPtr
< Kernel::PolarHandlePromise
>( ) ),
302 rear_( mid
), mid_( mid
), front_( mid
)
305 Concrete::PathPoint2D::PathPoint2D( Concrete::Length midx
, Concrete::Length midy
)
306 : rearState_( COMPLETE
), rearAngle_( std::numeric_limits
< double >::signaling_NaN( ) ), rearModulusPromise_( NullPtr
< Kernel::PolarHandlePromise
>( ) ),
307 frontState_( COMPLETE
), frontAngle_( std::numeric_limits
< double >::signaling_NaN( ) ), frontModulusPromise_( NullPtr
< Kernel::PolarHandlePromise
>( ) ),
309 rear_( new Concrete::Coords2D( midx
, midy
) ), mid_( rear_
), front_( rear_
)
312 Concrete::PathPoint2D::~PathPoint2D( )
314 if( rear_
!= 0 && rear_
!= mid_
)
322 if( front_
!= 0 && front_
!= mid_
)
328 Concrete::PathPoint2D
*
329 Concrete::PathPoint2D::transformed( const Lang::Transform2D
& tf
) const
331 Concrete::PathPoint2D
* res
= new Concrete::PathPoint2D( mid_
->transformedPtr( tf
) );
334 res
->rear_
= rear_
->transformedPtr( tf
);
338 res
->front_
= front_
->transformedPtr( tf
);
343 Concrete::PathPoint3D
*
344 Concrete::PathPoint2D::transformed( const Lang::Transform3D
& tf
) const
346 Concrete::PathPoint3D
* res
= new Concrete::PathPoint3D( mid_
->transformedPtr( tf
) );
349 res
->rear_
= rear_
->transformedPtr( tf
);
353 res
->front_
= front_
->transformedPtr( tf
);
358 Concrete::PathPoint3D
*
359 Concrete::PathPoint2D::typed_to3D( ) const
361 Concrete::PathPoint3D
* res
= new Concrete::PathPoint3D( *mid_
);
364 res
->rear_
= new Concrete::Coords3D( *rear_
);
368 res
->front_
= new Concrete::Coords3D( *front_
);
374 Concrete::PathPoint3D::PathPoint3D( const Concrete::PathPoint3D
& orig
)
375 : mid_( new Concrete::Coords3D( *orig
.mid_
) )
377 if( orig
.rear_
!= orig
.mid_
)
379 rear_
= new Concrete::Coords3D( *orig
.rear_
);
386 if( orig
.front_
!= orig
.mid_
)
388 front_
= new Concrete::Coords3D( *orig
.front_
);
396 Concrete::PathPoint3D::PathPoint3D( Concrete::Coords3D
* mid
)
397 : rear_( mid
), mid_( mid
), front_( mid
)
400 Concrete::PathPoint3D::PathPoint3D( const Concrete::Coords2D
& mid
)
401 : rear_( new Concrete::Coords3D( mid
) ), mid_( rear_
), front_( rear_
)
404 Concrete::PathPoint3D::PathPoint3D( Concrete::Length midx
, Concrete::Length midy
, Concrete::Length midz
)
405 : rear_( new Concrete::Coords3D( midx
, midy
, midz
) ), mid_( rear_
), front_( rear_
)
408 Concrete::PathPoint3D::~PathPoint3D( )
410 if( rear_
!= 0 && rear_
!= mid_
)
418 if( front_
!= 0 && front_
!= mid_
)
424 Concrete::PathPoint3D
*
425 Concrete::PathPoint3D::transformed( const Lang::Transform3D
& tf
) const
427 Concrete::PathPoint3D
* res
= new Concrete::PathPoint3D( mid_
->transformedPtr( tf
) );
430 res
->rear_
= rear_
->transformedPtr( tf
);
434 res
->front_
= front_
->transformedPtr( tf
);
439 Concrete::PathPoint2D
*
440 Concrete::PathPoint3D::make2D( Concrete::Length eyez
) const
442 Concrete::PathPoint2D
* res
= new Concrete::PathPoint2D( mid_
->make2D( eyez
) );
445 res
->rear_
= rear_
->make2D( eyez
);
449 res
->front_
= front_
->make2D( eyez
);
454 Lang::PathPoint2D::PathPoint2D( const Lang::PathPoint2D
& orig
)
455 : rear_( orig
.rear_
), mid_( orig
.mid_
), front_( orig
.front_
)
458 DISPATCHIMPL( PathPoint2D
);
460 Lang::PathPoint2D::PathPoint2D( RefCountPtr
< const Lang::Coords2D
> mid
)
461 : rear_( NullPtr
< Lang::Value
>( ) ), mid_( mid
), front_( NullPtr
< Lang::Value
>( ) )
464 Kernel::VariableHandle
465 Lang::PathPoint2D::getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
467 if( strcmp( fieldID
, "mid" ) == 0 )
469 return Kernel::VariableHandle( new Kernel::Variable( mid_
) );
471 if( strcmp( fieldID
, "rear" ) == 0 )
473 return Kernel::VariableHandle( new Kernel::Variable( rear_
) );
475 if( strcmp( fieldID
, "front" ) == 0 )
477 return Kernel::VariableHandle( new Kernel::Variable( front_
) );
479 throw Exceptions::NonExistentMember( getTypeName( ), fieldID
);
482 RefCountPtr
< const Lang::Geometric2D
>
483 Lang::PathPoint2D::transformed( const Lang::Transform2D
& tf
, const RefCountPtr
< const Lang::Geometric2D
> & self
) const
485 throw Exceptions::MiscellaneousRequirement( strrefdup( "A pathpoint by itself cannot be transformed." ) );
488 RefCountPtr
< const Lang::Geometric3D
>
489 Lang::PathPoint2D::to3D( const RefCountPtr
< const Lang::Geometric2D
> & self
) const
491 throw Exceptions::MiscellaneousRequirement( strrefdup( "A 2D pathpoint by itself cannot go 3D." ) );
495 Lang::PathPoint2D::gcMark( Kernel::GCMarkedSet
& marked
)
498 Lang::Value
* tmp
= const_cast< Lang::Value
* >( rear_
.getPtr( ) );
501 tmp
->gcMark( marked
);
505 const_cast< Lang::Coords2D
* >( mid_
.getPtr( ) )->gcMark( marked
);
508 Lang::Value
* tmp
= const_cast< Lang::Value
* >( front_
.getPtr( ) );
511 tmp
->gcMark( marked
);
517 RefCountPtr
< const Lang::Class
> Lang::PathPoint2D::TypeID( new Lang::SystemFinalClass( strrefdup( "PathPoint" ) ) );
518 TYPEINFOIMPL( PathPoint2D
);
521 Lang::PathPoint3D::PathPoint3D( const Lang::PathPoint3D
& orig
)
522 : rear_( orig
.rear_
), mid_( orig
.mid_
), front_( orig
.front_
)
525 DISPATCHIMPL( PathPoint3D
);
527 Lang::PathPoint3D::PathPoint3D( const RefCountPtr
< const Lang::Coords3D
> & mid
)
528 : rear_( NullPtr
< Lang::Coords3D
>( ) ), mid_( mid
), front_( NullPtr
< Lang::Coords3D
>( ) )
531 Kernel::VariableHandle
532 Lang::PathPoint3D::getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
534 if( strcmp( fieldID
, "mid" ) == 0 )
536 return Kernel::VariableHandle( new Kernel::Variable( mid_
) );
538 if( strcmp( fieldID
, "rear" ) == 0 )
540 return Kernel::VariableHandle( new Kernel::Variable( rear_
) );
542 if( strcmp( fieldID
, "front" ) == 0 )
544 return Kernel::VariableHandle( new Kernel::Variable( front_
) );
546 throw Exceptions::NonExistentMember( getTypeName( ), fieldID
);
550 Lang::PathPoint3D::elementaryJob( Lang::ElementaryPath3D
* pth
, Concrete::Coords3D
* basePoint
) const
552 Concrete::Coords3D
* newMid
= new Concrete::Coords3D( *basePoint
, *mid_
);
553 *basePoint
= *newMid
;
554 Concrete::PathPoint3D
* newPoint
= new Concrete::PathPoint3D( newMid
);
556 if( rear_
!= NullPtr
< const Lang::Coords3D
>( ) )
558 newPoint
->rear_
= new Concrete::Coords3D( *basePoint
, *rear_
);
561 if( front_
!= NullPtr
< const Lang::Coords3D
>( ) )
563 newPoint
->front_
= new Concrete::Coords3D( *basePoint
, *front_
);
566 pth
->push_back( newPoint
);
569 RefCountPtr
< const Lang::Geometric3D
>
570 Lang::PathPoint3D::transformed( const Lang::Transform3D
& tf
, const RefCountPtr
< const Lang::Geometric3D
> & self
) const
572 PathPoint3D
* res
= new Lang::PathPoint3D( RefCountPtr
< const Lang::Coords3D
>( mid_
->transformedPtr( tf
) ) );
574 if( rear_
!= NullPtr
< const Lang::Coords3D
>( ) )
576 res
->rear_
= RefCountPtr
< const Lang::Coords3D
>( rear_
->transformedPtr( tf
) );
579 if( front_
!= NullPtr
< const Lang::Coords3D
>( ) )
581 res
->front_
= RefCountPtr
< const Lang::Coords3D
>( front_
->transformedPtr( tf
) );
584 return RefCountPtr
< const Lang::Geometric3D
>( res
);
587 RefCountPtr
< const Lang::Geometric2D
>
588 Lang::PathPoint3D::to2D( const Kernel::PassedDyn
& dyn
, const RefCountPtr
< const Lang::Geometric3D
> & self
) const
590 Concrete::Length eyez
= dyn
->getEyeZ( );
591 PathPoint2D
* res
= new Lang::PathPoint2D( mid_
->make2D( eyez
) );
593 if( rear_
!= NullPtr
< const Lang::Coords3D
>( ) )
595 res
->rear_
= rear_
->make2D( eyez
);
598 if( front_
!= NullPtr
< const Lang::Coords3D
>( ) )
600 res
->front_
= front_
->make2D( eyez
);
603 return RefCountPtr
< const Lang::Geometric2D
>( res
);
607 Lang::PathPoint3D::gcMark( Kernel::GCMarkedSet
& marked
)
610 Lang::Coords3D
* tmp
= const_cast< Lang::Coords3D
* >( rear_
.getPtr( ) );
613 tmp
->gcMark( marked
);
617 const_cast< Lang::Coords3D
* >( mid_
.getPtr( ) )->gcMark( marked
);
620 Lang::Coords3D
* tmp
= const_cast< Lang::Coords3D
* >( front_
.getPtr( ) );
623 tmp
->gcMark( marked
);
628 RefCountPtr
< const Lang::Class
> Lang::PathPoint3D::TypeID( new Lang::SystemFinalClass( strrefdup( "PathPoint" ) ) );
629 TYPEINFOIMPL( PathPoint3D
);
632 Lang::Path2D::Path2D( )
636 DISPATCHIMPL( Path2D
);
638 Lang::Path2D::~Path2D( )
642 Lang::Path2D::close( )
647 Lang::Path2D::isClosed( ) const
652 RefCountPtr
< const Lang::Geometric2D
>
653 Lang::Path2D::transformed( const Lang::Transform2D
& tf
, const RefCountPtr
< const Lang::Geometric2D
> & self
) const
655 typedef const Lang::Path2D ArgType
;
656 RefCountPtr
< ArgType
> selfTyped
= self
.down_cast
< ArgType
>( );
657 if( selfTyped
== NullPtr
< ArgType
>( ) )
659 throw Exceptions::InternalError( strrefdup( "Path2D::to3D: self was of unexpected type." ) );
662 return selfTyped
->typed_transformed( tf
);
665 RefCountPtr
< const Lang::Geometric3D
>
666 Lang::Path2D::to3D( const RefCountPtr
< const Lang::Geometric2D
> & self
) const
668 typedef const Lang::Path2D ArgType
;
669 RefCountPtr
< ArgType
> selfTyped
= self
.down_cast
< ArgType
>( );
670 if( selfTyped
== NullPtr
< ArgType
>( ) )
672 throw Exceptions::InternalError( strrefdup( "Path2D::to3D: self was of unexpected type." ) );
675 return selfTyped
->typed_to3D( selfTyped
);
678 RefCountPtr
< const Lang::Class
> Lang::Path2D::TypeID( new Lang::SystemFinalClass( strrefdup( "Path" ) ) );
679 TYPEINFOIMPL( Path2D
);
682 Lang::CompositePath2D::CompositePath2D( )
683 : elementaryPath_( NullPtr
< const ElementaryPath2D
>( ) )
686 DISPATCHIMPL( CompositePath2D
);
688 Lang::CompositePath2D::~CompositePath2D( )
691 Kernel::VariableHandle
692 Lang::CompositePath2D::getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
694 computeElementaryPath( );
695 return elementaryPath_
->getField( fieldID
, elementaryPath_
);
698 RefCountPtr
< const Lang::Path2D
>
699 Lang::CompositePath2D::typed_transformed( const Lang::Transform2D
& tf
) const
701 computeElementaryPath( );
702 return elementaryPath_
->typed_transformed( tf
);
705 RefCountPtr
< const Lang::Path3D
>
706 Lang::CompositePath2D::typed_to3D( const RefCountPtr
< const Lang::Path2D
> & self
) const
708 computeElementaryPath( );
709 return RefCountPtr
< const Lang::Path3D
>( new Lang::Path2Din3D( elementaryPath_
) );
713 Lang::CompositePath2D::writePath( ostream
& os
) const
715 computeElementaryPath( );
716 elementaryPath_
->writePath( os
);
719 RefCountPtr
< const Lang::ElementaryPath2D
>
720 Lang::CompositePath2D::getElementaryPath( ) const
722 computeElementaryPath( );
723 return elementaryPath_
;
727 Lang::CompositePath2D::show( std::ostream
& os
) const
729 os
<< "Composite subpath" ;
733 Lang::ClosedPath2D::ClosedPath2D( RefCountPtr
< const Lang::Path2D
> openPath
)
734 : openPath_( openPath
)
739 Lang::ClosedPath2D::~ClosedPath2D( )
742 DISPATCHIMPL( ClosedPath2D
);
745 Lang::ClosedPath2D::elementaryJob( std::stack
< const Lang::Value
* > * nodeStack
, Lang::ElementaryPath2D
* pth
, Concrete::Coords2D
* basePoint
) const
747 openPath_
->elementaryJob( nodeStack
, pth
, basePoint
);
749 * Although this seems incorrect, as the fact that this path is closed will not be respected,
750 * this should not be a problem since it is not allowed to connect closed paths with anything.
755 Lang::ClosedPath2D::gcMark( Kernel::GCMarkedSet
& marked
)
757 const_cast< Lang::Path2D
* >( openPath_
.getPtr( ) )->gcMark( marked
);
761 Lang::Connection2D::Connection2D( Kernel::ValueRef rear
, Kernel::ValueRef front
)
762 : rear_( rear
), front_( front
)
765 DISPATCHIMPL( Connection2D
);
767 Lang::Connection2D::~Connection2D( )
771 Lang::Connection2D::elementaryJob( std::stack
< const Lang::Value
* > * nodeStack
, Lang::ElementaryPath2D
* pth
, Concrete::Coords2D
* basePoint
) const
773 nodeStack
->push( front_
.getPtr( ) );
774 nodeStack
->push( rear_
.getPtr( ) );
778 Lang::Connection2D::gcMark( Kernel::GCMarkedSet
& marked
)
780 const_cast< Lang::Value
* >( rear_
.getPtr( ) )->gcMark( marked
);
781 const_cast< Lang::Value
* >( front_
.getPtr( ) )->gcMark( marked
);
785 Lang::SinglePointPath2D::SinglePointPath2D( Kernel::ValueRef thePoint
)
786 : thePoint_( thePoint
)
789 DISPATCHIMPL( SinglePointPath2D
);
791 Lang::SinglePointPath2D::~SinglePointPath2D( )
795 Lang::SinglePointPath2D::elementaryJob( std::stack
< const Lang::Value
* > * nodeStack
, Lang::ElementaryPath2D
* pth
, Concrete::Coords2D
* basePoint
) const
797 nodeStack
->push( thePoint_
.getPtr( ) );
801 Lang::SinglePointPath2D::gcMark( Kernel::GCMarkedSet
& marked
)
803 const_cast< Lang::Value
* >( thePoint_
.getPtr( ) )->gcMark( marked
);
807 Lang::HeadedPath2D::HeadedPath2D( Kernel::ValueRef rear
, const RefCountPtr
< const Lang::ElementaryPath2D
> & bodyPath
, Kernel::ValueRef front
)
808 : bodyPath_( new Lang::HeadedPath2D_helper( bodyPath
) ), rearPathPoint_( NullPtr
< const Lang::Value
>( ) ), frontPathPoint_( NullPtr
< const Lang::Value
>( ) )
810 if( bodyPath
->isClosed( ) )
812 throw Exceptions::InternalError( strrefdup( "Attempt to create closed but headed path." ) );
814 if( bodyPath
->empty( ) )
816 throw Exceptions::InternalError( strrefdup( "Attempt to create empty but headed path." ) );
819 if( bodyPath
->size( ) == 1 )
821 Lang::ElementaryPath2D::const_iterator i
= bodyPath
->begin( );
822 Lang::PathPoint2D
* newPoint
= new Lang::PathPoint2D( RefCountPtr
< const Lang::Coords2D
>( new Lang::Coords2D( *( (*i
)->mid_
) ) ) );
823 newPoint
->rear_
= rear
;
824 newPoint
->front_
= front
;
825 rearPathPoint_
= Kernel::ValueRef( newPoint
);
830 // We reach here if there's more than 1 point in bodyPath
833 Lang::ElementaryPath2D::const_reverse_iterator i
= bodyPath
->rbegin( );
834 Lang::PathPoint2D
* newPoint
= new Lang::PathPoint2D( RefCountPtr
< const Lang::Coords2D
>( new Lang::Coords2D( *( (*i
)->mid_
) ) ) );
835 if( (*i
)->rear_
!= 0 )
837 newPoint
->rear_
= RefCountPtr
< const Lang::Coords2D
>( new Lang::Coords2D( *( (*i
)->rear_
) ) );
839 newPoint
->front_
= front
;
840 frontPathPoint_
= Kernel::ValueRef( newPoint
);
843 Lang::ElementaryPath2D::const_iterator i
= bodyPath
->begin( );
844 Lang::PathPoint2D
* newPoint
= new Lang::PathPoint2D( RefCountPtr
< const Lang::Coords2D
>( new Lang::Coords2D( *( (*i
)->mid_
) ) ) );
845 if( (*i
)->front_
!= 0 )
847 newPoint
->front_
= RefCountPtr
< const Lang::Coords2D
>( new Lang::Coords2D( *( (*i
)->front_
) ) );
849 newPoint
->rear_
= rear
;
850 rearPathPoint_
= Kernel::ValueRef( newPoint
);
854 DISPATCHIMPL( HeadedPath2D
);
856 Lang::HeadedPath2D::~HeadedPath2D( )
860 Lang::HeadedPath2D::elementaryJob( std::stack
< const Lang::Value
* > * nodeStack
, Lang::ElementaryPath2D
* pth
, Concrete::Coords2D
* basePoint
) const
862 if( frontPathPoint_
== NullPtr
< const Lang::Value
>( ) )
864 // This means that there was just a single point in bodyPath
866 nodeStack
->push( rearPathPoint_
.getPtr( ) );
871 nodeStack
->push( frontPathPoint_
.getPtr( ) );
872 nodeStack
->push( bodyPath_
.getPtr( ) );
873 nodeStack
->push( rearPathPoint_
.getPtr( ) );
878 Lang::HeadedPath2D::gcMark( Kernel::GCMarkedSet
& marked
)
880 const_cast< Lang::HeadedPath2D_helper
* >( bodyPath_
.getPtr( ) )->gcMark( marked
);
881 const_cast< Lang::Value
* >( rearPathPoint_
.getPtr( ) )->gcMark( marked
);
882 const_cast< Lang::Value
* >( frontPathPoint_
.getPtr( ) )->gcMark( marked
);
886 Lang::HeadedPath2D_helper::HeadedPath2D_helper( const RefCountPtr
< const Lang::ElementaryPath2D
> & bodyPath
)
887 : bodyPath_( bodyPath
)
890 Lang::HeadedPath2D_helper::~HeadedPath2D_helper( )
894 Lang::HeadedPath2D_helper::elementaryJob( std::stack
< const Lang::Value
* > * nodeStack
, Lang::ElementaryPath2D
* pth
, Concrete::Coords2D
* basePoint
) const
896 if( bodyPath_
->size( ) <= 1 )
898 throw Exceptions::InternalError( strrefdup( "HeadedPath2D_helper::elementaryJob was unexpectedly called with a short path." ) );
901 Lang::ElementaryPath2D::const_iterator i
= bodyPath_
->begin( );
903 Lang::ElementaryPath2D::const_iterator end
= bodyPath_
->end( );
905 for( ; i
!= end
; ++i
)
907 pth
->push_back( new Concrete::PathPoint2D( **i
) );
910 --i
; /* Go back to the last point added to pth. */
911 *basePoint
= *((*i
)->mid_
);
915 Lang::HeadedPath2D_helper::gcMark( Kernel::GCMarkedSet
& marked
)
917 const_cast< Lang::ElementaryPath2D
* >( bodyPath_
.getPtr( ) )->gcMark( marked
);
922 Lang::MultiPath2D::MultiPath2D( )
925 DISPATCHIMPL( MultiPath2D
);
927 Lang::MultiPath2D::~MultiPath2D( )
931 Lang::MultiPath2D::clone( ) const
933 Lang::MultiPath2D
* res
= new Lang::MultiPath2D( );
934 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
936 res
->push_back( *i
);
941 RefCountPtr
< const Lang::Class
> Lang::MultiPath2D::TypeID( new Lang::SystemFinalClass( strrefdup( "MultiPath" ) ) );
942 TYPEINFOIMPL( MultiPath2D
);
945 Lang::MultiPath2D::show( std::ostream
& os
) const
947 os
<< "Path with " << size( ) << " subpaths" ;
950 Kernel::VariableHandle
951 Lang::MultiPath2D::getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
953 if( strcmp( fieldID
, "list" ) == 0 )
955 RefCountPtr
< const Lang::SingleList
> res
= Lang::THE_CONS_NULL
;
956 for( const_reverse_iterator i
= rbegin( ); i
!= rend( ); ++i
)
958 res
= RefCountPtr
< const Lang::SingleList
>( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( *i
) ),
961 return Kernel::VariableHandle( new Kernel::Variable( res
) );
963 throw Exceptions::NonExistentMember( getTypeName( ), fieldID
);
966 RefCountPtr
< const Lang::Geometric2D
>
967 Lang::MultiPath2D::transformed( const Lang::Transform2D
& tf
, const RefCountPtr
< const Lang::Geometric2D
> & self
) const
969 Lang::MultiPath2D
* res
= new Lang::MultiPath2D( );
970 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
972 res
->push_back( (*i
)->typed_transformed( tf
) );
974 return RefCountPtr
< Lang::Geometric2D
>( res
);
977 RefCountPtr
< const Lang::Geometric3D
>
978 Lang::MultiPath2D::to3D( const RefCountPtr
< const Lang::Geometric2D
> & self
) const
980 Lang::MultiPath3D
* res
= new Lang::MultiPath3D( );
981 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
983 res
->push_back( (*i
)->typed_to3D( *i
) );
985 return RefCountPtr
< const Lang::Geometric3D
>( res
);
989 Lang::MultiPath2D::writePath( ostream
& os
) const
991 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
993 (*i
)->writePath( os
);
998 Lang::MultiPath2D::gcMark( Kernel::GCMarkedSet
& marked
)
1000 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
1002 const_cast< Path2D
* >( i
->getPtr( ) )->gcMark( marked
);
1007 Lang::MultiPath3D::MultiPath3D( )
1010 DISPATCHIMPL( MultiPath3D
);
1012 Lang::MultiPath3D::~MultiPath3D( )
1016 Lang::MultiPath3D::clone( ) const
1018 Lang::MultiPath3D
* res
= new Lang::MultiPath3D( );
1019 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
1021 res
->push_back( *i
);
1026 RefCountPtr
< const Lang::Class
> Lang::MultiPath3D::TypeID( new Lang::SystemFinalClass( strrefdup( "MultiPath3D" ) ) );
1027 TYPEINFOIMPL( MultiPath3D
);
1030 Lang::MultiPath3D::show( std::ostream
& os
) const
1032 os
<< "3D path with " << size( ) << " subpaths" ;
1035 Kernel::VariableHandle
1036 Lang::MultiPath3D::getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
1038 if( strcmp( fieldID
, "list" ) == 0 )
1040 RefCountPtr
< const Lang::SingleList
> res
= Lang::THE_CONS_NULL
;
1041 for( const_reverse_iterator i
= rbegin( ); i
!= rend( ); ++i
)
1043 res
= RefCountPtr
< const Lang::SingleList
>( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( *i
) ),
1046 return Kernel::VariableHandle( new Kernel::Variable( res
) );
1048 throw Exceptions::NonExistentMember( getTypeName( ), fieldID
);
1051 RefCountPtr
< const Lang::Geometric3D
>
1052 Lang::MultiPath3D::transformed( const Lang::Transform3D
& tf
, const RefCountPtr
< const Lang::Geometric3D
> & self
) const
1054 Lang::MultiPath3D
* res
= new Lang::MultiPath3D( );
1055 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
1057 res
->push_back( (*i
)->typed_transformed( tf
) );
1059 return RefCountPtr
< Lang::Geometric3D
>( res
);
1062 RefCountPtr
< const Lang::Geometric2D
>
1063 Lang::MultiPath3D::to2D( const Kernel::PassedDyn
& dyn
, const RefCountPtr
< const Lang::Geometric3D
> & self
) const
1065 Concrete::Length eyez
= dyn
->getEyeZ( );
1066 Lang::MultiPath2D
* res
= new Lang::MultiPath2D( );
1067 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
1069 res
->push_back( (*i
)->make2D( eyez
) );
1071 return RefCountPtr
< const Lang::Geometric2D
>( res
);
1075 Lang::MultiPath3D::gcMark( Kernel::GCMarkedSet
& marked
)
1077 for( const_iterator i
= begin( ); i
!= end( ); ++i
)
1079 const_cast< Path3D
* >( i
->getPtr( ) )->gcMark( marked
);
1084 Lang::Path3D::Path3D( )
1088 DISPATCHIMPL( Path3D
);
1090 Lang::Path3D::~Path3D( )
1094 Lang::Path3D::close( )
1099 Lang::Path3D::isClosed( ) const
1104 RefCountPtr
< const Lang::Geometric3D
>
1105 Lang::Path3D::transformed( const Lang::Transform3D
& tf
, const RefCountPtr
< const Lang::Geometric3D
> & self
) const
1107 typedef const Lang::Path3D ArgType
;
1108 RefCountPtr
< ArgType
> selfTyped
= self
.down_cast
< ArgType
>( );
1109 if( selfTyped
== NullPtr
< ArgType
>( ) )
1111 throw Exceptions::InternalError( strrefdup( "Path3D::to3D: self was of unexpected type." ) );
1114 return selfTyped
->typed_transformed( tf
);
1117 RefCountPtr
< const Lang::Geometric2D
>
1118 Lang::Path3D::to2D( const Kernel::PassedDyn
& dyn
, const RefCountPtr
< const Lang::Geometric3D
> & self
) const
1120 Concrete::Length eyez
= dyn
->getEyeZ( );
1121 return this->make2D( eyez
);
1124 RefCountPtr
< const Lang::Class
> Lang::Path3D::TypeID( new Lang::SystemFinalClass( strrefdup( "Path3D" ) ) );
1125 TYPEINFOIMPL( Path3D
);
1128 Lang::Path2Din3D::Path2Din3D( const RefCountPtr
< const Lang::ElementaryPath2D
> & elementaryPath2D
)
1129 : elementaryPath2D_( elementaryPath2D
)
1131 if( elementaryPath2D_
->isClosed( ) )
1137 Lang::Path2Din3D::~Path2Din3D( )
1140 RefCountPtr
< const Lang::ElementaryPath2D
>
1141 Lang::Path2Din3D::make2D( Concrete::Length eyez
) const
1143 // Since this path has not been transformed, it's "already" in 2D.
1145 return elementaryPath2D_
;
1148 RefCountPtr
< const Lang::Path3D
>
1149 Lang::Path2Din3D::typed_transformed( const Lang::Transform3D
& tf
) const
1151 return elementaryPath2D_
->elementaryTransformed( tf
);
1155 Lang::Path2Din3D::elementaryJob( std::stack
< const Lang::Path3D
* > * nodeStack
, Lang::ElementaryPath3D
* pth
, Concrete::Coords3D
* basePoint
) const
1157 for( Lang::ElementaryPath2D::const_iterator i
= elementaryPath2D_
->begin( ); i
!= elementaryPath2D_
->end( ); ++i
)
1159 pth
->push_back( (*i
)->typed_to3D( ) );
1161 *basePoint
= *(elementaryPath2D_
->back( )->mid_
);
1165 Lang::Path2Din3D::gcMark( Kernel::GCMarkedSet
& marked
)
1167 const_cast< Lang::ElementaryPath2D
* >( elementaryPath2D_
.getPtr( ) )->gcMark( marked
);
1172 Lang::ClosedPath3D::ClosedPath3D( RefCountPtr
< const Lang::Path3D
> openPath
)
1173 : openPath_( openPath
)
1178 Lang::ClosedPath3D::~ClosedPath3D( )
1181 DISPATCHIMPL( ClosedPath3D
);
1184 Lang::ClosedPath3D::elementaryJob( std::stack
< const Lang::Path3D
* > * nodeStack
, Lang::ElementaryPath3D
* pth
, Concrete::Coords3D
* basePoint
) const
1186 openPath_
->elementaryJob( nodeStack
, pth
, basePoint
);
1188 * Although this seems incorrect, as the fact that this path is closed will not be respected,
1189 * this should not be a problem since it is not allowed to connect closed paths with anything.
1194 Lang::ClosedPath3D::gcMark( Kernel::GCMarkedSet
& marked
)
1196 const_cast< Lang::Path3D
* >( openPath_
.getPtr( ) )->gcMark( marked
);
1200 Lang::Connection3D::Connection3D( const RefCountPtr
< const Lang::Path3D
> & rear
, const RefCountPtr
< const Lang::Path3D
> & front
)
1201 : rear_( rear
), front_( front
)
1204 Lang::Connection3D::~Connection3D( )
1208 Lang::Connection3D::elementaryJob( std::stack
< const Lang::Path3D
* > * nodeStack
, Lang::ElementaryPath3D
* pth
, Concrete::Coords3D
* basePoint
) const
1210 nodeStack
->push( front_
.getPtr( ) );
1211 nodeStack
->push( rear_
.getPtr( ) );
1215 Lang::Connection3D::gcMark( Kernel::GCMarkedSet
& marked
)
1217 const_cast< Lang::Path3D
* >( rear_
.getPtr( ) )->gcMark( marked
);
1218 const_cast< Lang::Path3D
* >( front_
.getPtr( ) )->gcMark( marked
);
1221 DISPATCHIMPL( Connection3D
);
1224 Lang::SinglePointPath3D::SinglePointPath3D( const RefCountPtr
< const Lang::PathPoint3D
> & thePoint
)
1225 : thePoint_( thePoint
)
1228 Lang::SinglePointPath3D::SinglePointPath3D( const RefCountPtr
< const Lang::Coords3D
> & mid
)
1229 : thePoint_( new Lang::PathPoint3D( mid
) )
1232 DISPATCHIMPL( SinglePointPath3D
);
1234 Lang::SinglePointPath3D::~SinglePointPath3D( )
1238 Lang::SinglePointPath3D::elementaryJob( std::stack
< const Lang::Path3D
* > * nodeStack
, Lang::ElementaryPath3D
* pth
, Concrete::Coords3D
* basePoint
) const
1240 thePoint_
->elementaryJob( pth
, basePoint
);
1244 Lang::SinglePointPath3D::gcMark( Kernel::GCMarkedSet
& marked
)
1246 const_cast< Lang::PathPoint3D
* >( thePoint_
.getPtr( ) )->gcMark( marked
);
1250 Lang::CompositePath3D::CompositePath3D( )
1251 : elementaryPath_( NullPtr
< const ElementaryPath3D
>( ) )
1254 DISPATCHIMPL( CompositePath3D
);
1256 Lang::CompositePath3D::~CompositePath3D( )
1259 Kernel::VariableHandle
1260 Lang::CompositePath3D::getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
1262 computeElementaryPath( );
1263 return elementaryPath_
->getField( fieldID
, elementaryPath_
);
1266 RefCountPtr
< const Lang::Path3D
>
1267 Lang::CompositePath3D::typed_transformed( const Lang::Transform3D
& tf
) const
1269 computeElementaryPath( );
1270 return elementaryPath_
->typed_transformed( tf
);
1273 RefCountPtr
< const Lang::ElementaryPath2D
>
1274 Lang::CompositePath3D::make2D( Concrete::Length eyez
) const
1276 computeElementaryPath( );
1277 return elementaryPath_
->make2D( eyez
);
1280 RefCountPtr
< const Lang::ElementaryPath3D
>
1281 Lang::CompositePath3D::getElementaryPath( ) const
1283 computeElementaryPath( );
1285 return elementaryPath_
;
1289 Lang::CompositePath3D::show( std::ostream
& os
) const
1291 os
<< "Composite subpath in 3D" ;
1295 Lang::CompositePath3D::computeElementaryPath( ) const
1297 if( elementaryPath_
!= NullPtr
< const Lang::ElementaryPath3D
>( ) )
1301 Lang::ElementaryPath3D
* pth
= new Lang::ElementaryPath3D
;
1303 Concrete::Coords3D
basePoint( 0, 0, 0 );
1305 std::stack
< const Lang::Path3D
* > nodeStack
;
1306 nodeStack
.push( this );
1307 while( ! nodeStack
.empty( ) )
1309 const Lang::Path3D
* node
= nodeStack
.top( );
1311 node
->elementaryJob( & nodeStack
, pth
, & basePoint
);
1319 elementaryPath_
= RefCountPtr
< const Lang::ElementaryPath3D
>( pth
);
1323 Lang::HeadedPath3D::HeadedPath3D( Kernel::ValueRef rear
, const RefCountPtr
< const Lang::ElementaryPath3D
> & bodyPath
, Kernel::ValueRef front
)
1324 : bodyPath_( new Lang::HeadedPath3D_helper( bodyPath
) ),
1325 rearPathPoint_( NullPtr
< const Lang::SinglePointPath3D
>( ) ),
1326 frontPathPoint_( NullPtr
< const Lang::SinglePointPath3D
>( ) )
1328 if( bodyPath
->isClosed( ) )
1330 throw Exceptions::InternalError( strrefdup( "Attempt to create closed but headed path." ) );
1332 if( bodyPath
->empty( ) )
1334 throw Exceptions::InternalError( strrefdup( "Attempt to create empty but headed path." ) );
1336 if( bodyPath
->size( ) == 1 )
1338 Lang::ElementaryPath3D::const_iterator i
= bodyPath
->begin( );
1339 Lang::PathPoint3D
* newPoint
= new Lang::PathPoint3D( RefCountPtr
< const Lang::Coords3D
>( new Lang::Coords3D( *( (*i
)->mid_
) ) ) );
1340 newPoint
->rear_
= rear
;
1341 newPoint
->front_
= front
;
1342 rearPathPoint_
= RefCountPtr
< const Lang::SinglePointPath3D
>( new Lang::SinglePointPath3D( RefCountPtr
< const Lang::PathPoint3D
>( newPoint
) ) );
1347 // We reach here if there's more than one point in the body.
1350 Lang::ElementaryPath3D::const_reverse_iterator i
= bodyPath
->rbegin( );
1351 Lang::PathPoint3D
* newPoint
= new Lang::PathPoint3D( RefCountPtr
< const Lang::Coords3D
>( new Lang::Coords3D( *( (*i
)->mid_
) ) ) );
1352 if( (*i
)->rear_
!= 0 )
1354 newPoint
->rear_
= RefCountPtr
< const Lang::Coords3D
>( new Lang::Coords3D( *( (*i
)->rear_
) ) );
1356 newPoint
->front_
= front
;
1357 frontPathPoint_
= RefCountPtr
< const Lang::SinglePointPath3D
>( new Lang::SinglePointPath3D( RefCountPtr
< const Lang::PathPoint3D
>( newPoint
) ) );
1360 Lang::ElementaryPath3D::const_iterator i
= bodyPath
->begin( );
1361 Lang::PathPoint3D
* newPoint
= new Lang::PathPoint3D( RefCountPtr
< const Lang::Coords3D
>( new Lang::Coords3D( *( (*i
)->mid_
) ) ) );
1362 if( (*i
)->front_
!= 0 )
1364 newPoint
->front_
= RefCountPtr
< const Lang::Coords3D
>( new Lang::Coords3D( *( (*i
)->front_
) ) );
1366 newPoint
->rear_
= rear
;
1367 rearPathPoint_
= RefCountPtr
< const Lang::SinglePointPath3D
>( new Lang::SinglePointPath3D( RefCountPtr
< const Lang::PathPoint3D
>( newPoint
) ) );
1372 DISPATCHIMPL( HeadedPath3D
);
1374 Lang::HeadedPath3D::~HeadedPath3D( )
1378 Lang::HeadedPath3D::elementaryJob( std::stack
< const Lang::Path3D
* > * nodeStack
, Lang::ElementaryPath3D
* pth
, Concrete::Coords3D
* basePoint
) const
1380 if( frontPathPoint_
== NullPtr
< const Lang::SinglePointPath3D
>( ) )
1382 // This means that there was just a single point in bodyPath
1384 nodeStack
->push( rearPathPoint_
.getPtr( ) );
1389 nodeStack
->push( frontPathPoint_
.getPtr( ) );
1390 nodeStack
->push( bodyPath_
.getPtr( ) );
1391 nodeStack
->push( rearPathPoint_
.getPtr( ) );
1396 Lang::HeadedPath3D::gcMark( Kernel::GCMarkedSet
& marked
)
1398 const_cast< Lang::HeadedPath3D_helper
* >( bodyPath_
.getPtr( ) )->gcMark( marked
);
1399 const_cast< Lang::SinglePointPath3D
* >( rearPathPoint_
.getPtr( ) )->gcMark( marked
);
1400 const_cast< Lang::SinglePointPath3D
* >( frontPathPoint_
.getPtr( ) )->gcMark( marked
);
1404 Lang::HeadedPath3D_helper::HeadedPath3D_helper( const RefCountPtr
< const Lang::ElementaryPath3D
> & bodyPath
)
1405 : bodyPath_( bodyPath
)
1408 Lang::HeadedPath3D_helper::~HeadedPath3D_helper( )
1412 Lang::HeadedPath3D_helper::elementaryJob( std::stack
< const Lang::Path3D
* > * nodeStack
, Lang::ElementaryPath3D
* pth
, Concrete::Coords3D
* basePoint
) const
1414 if( bodyPath_
->size( ) <= 1 )
1416 throw Exceptions::InternalError( strrefdup( "HeadedPath3D_helper::elementaryJob was unexpectedly called with a short path." ) );
1419 Lang::ElementaryPath3D::const_iterator i
= bodyPath_
->begin( );
1421 Lang::ElementaryPath3D::const_iterator end
= bodyPath_
->end( );
1423 for( ; i
!= end
; ++i
)
1425 pth
->push_back( new Concrete::PathPoint3D( **i
) );
1428 --i
; /* Go back to the last point added to pth. */
1429 *basePoint
= *((*i
)->mid_
);
1433 Lang::HeadedPath3D_helper::gcMark( Kernel::GCMarkedSet
& marked
)
1435 const_cast< Lang::ElementaryPath3D
* >( bodyPath_
.getPtr( ) )->gcMark( marked
);