353 lines
9.5 KiB
C++
353 lines
9.5 KiB
C++
/*! \file src/record.cpp
|
|
\author Klaas Holwerda or Julian Smart
|
|
|
|
Copyright: 2001-2004 (C) Klaas Holwerda
|
|
|
|
Licence: see kboollicense.txt
|
|
|
|
RCS-ID: $Id: record.cpp,v 1.3 2008/06/04 21:23:22 titato Exp $
|
|
*/
|
|
|
|
#include "kbool/booleng.h"
|
|
#include "kbool/record.h"
|
|
#include "kbool/node.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#define LNK _line.GetLink()
|
|
|
|
//int r_index=-1;
|
|
//void* _Record_Pool[30];
|
|
|
|
//void DeleteRecordPool()
|
|
//{
|
|
// while (r_index!=-1)
|
|
// {
|
|
// free( _Record_Pool[r_index--]);
|
|
// }
|
|
//}
|
|
|
|
Record::~Record()
|
|
{}
|
|
|
|
|
|
//void* Record::operator new(size_t size)
|
|
//{
|
|
//
|
|
// if (r_index!=-1)
|
|
// {
|
|
// return _Record_Pool[r_index--];
|
|
// }
|
|
//
|
|
// return malloc(size);
|
|
//}
|
|
|
|
//void Record::operator delete(void* recordptr)
|
|
//{
|
|
//
|
|
// if (r_index < 28)
|
|
// {
|
|
// _Record_Pool[++r_index]= recordptr;
|
|
// return;
|
|
// }
|
|
//
|
|
// free (recordptr);
|
|
//}
|
|
|
|
//void Record::deletepool()
|
|
//{
|
|
//
|
|
// while (r_index!=-1)
|
|
// {
|
|
// free( _Record_Pool[r_index--]);
|
|
// }
|
|
//}
|
|
|
|
Record::Record( KBoolLink* link, Bool_Engine* GC )
|
|
: _line( GC )
|
|
{
|
|
_GC = GC;
|
|
_dir = GO_RIGHT;
|
|
_a = 0;
|
|
_b = 0;
|
|
_line.Set( link );
|
|
_line.CalculateLineParameters();
|
|
}
|
|
|
|
|
|
//when the dimensions of a link for a record changes, its line parameters need to be recalculated
|
|
void Record::SetNewLink( KBoolLink* link )
|
|
{
|
|
_line.Set( link );
|
|
_line.CalculateLineParameters();
|
|
}
|
|
|
|
//for beams calculate the ysp on the low scanline
|
|
void Record::Calc_Ysp( Node* low )
|
|
{
|
|
if ( ( LNK->GetEndNode() == low ) || ( LNK->GetBeginNode() == low ) )
|
|
{
|
|
_ysp = low->GetY();
|
|
return;
|
|
}
|
|
|
|
if ( LNK->GetEndNode()->GetX() == LNK->GetBeginNode()->GetX() )
|
|
_ysp = low->GetY(); //flatlink only in flatbeams
|
|
else if ( LNK->GetEndNode()->GetX() == low->GetX() )
|
|
_ysp = LNK->GetEndNode()->GetY();
|
|
else if ( LNK->GetBeginNode()->GetX() == low->GetX() )
|
|
_ysp = LNK->GetBeginNode()->GetY();
|
|
else
|
|
_ysp = _line.Calculate_Y_from_X( low->GetX() );
|
|
}
|
|
|
|
//to set the _dir for new links in the beam
|
|
void Record::Set_Flags()
|
|
{
|
|
if ( LNK->GetEndNode()->GetX() == LNK->GetBeginNode()->GetX() ) //flatlink ?
|
|
{ //only happens in flat beams
|
|
if ( LNK->GetEndNode()->GetY() < LNK->GetBeginNode()->GetY() )
|
|
_dir = GO_RIGHT;
|
|
else
|
|
_dir = GO_LEFT;
|
|
}
|
|
else
|
|
{
|
|
if ( LNK->GetEndNode()->GetX() > LNK->GetBeginNode()->GetX() )
|
|
_dir = GO_RIGHT;
|
|
else
|
|
_dir = GO_LEFT;
|
|
}
|
|
}
|
|
|
|
KBoolLink* Record::GetLink()
|
|
{
|
|
return LNK;
|
|
}
|
|
|
|
B_INT Record::Ysp()
|
|
{
|
|
return _ysp;
|
|
}
|
|
|
|
void Record::SetYsp( B_INT ysp )
|
|
{
|
|
_ysp = ysp;
|
|
}
|
|
|
|
DIRECTION Record::Direction()
|
|
{
|
|
return DIRECTION( _dir );
|
|
}
|
|
|
|
bool Record::Calc_Left_Right( Record* record_above_me )
|
|
{
|
|
bool par = false;
|
|
|
|
if ( !record_above_me ) //null if no record above
|
|
{ _a = 0;_b = 0; }
|
|
else
|
|
{
|
|
_a = record_above_me->_a;
|
|
_b = record_above_me->_b;
|
|
}
|
|
|
|
switch ( _dir & 1 )
|
|
{
|
|
case GO_LEFT : if ( LNK->Group() == GROUP_A )
|
|
{
|
|
LNK->SetRightA( ( bool )( _a > 0 ) );
|
|
|
|
if ( _GC->GetWindingRule() )
|
|
LNK->GetInc() ? _a++ : _a--;
|
|
else
|
|
{ //ALTERNATE
|
|
if ( _a )
|
|
_a = 0;
|
|
else
|
|
_a = 1;
|
|
}
|
|
|
|
LNK->SetLeftA( ( bool )( _a > 0 ) );
|
|
LNK->SetLeftB( ( bool )( _b > 0 ) );
|
|
LNK->SetRightB( ( bool )( _b > 0 ) );
|
|
}
|
|
else
|
|
{
|
|
LNK->SetRightA( ( bool )( _a > 0 ) );
|
|
LNK->SetLeftA( ( bool )( _a > 0 ) );
|
|
LNK->SetRightB( ( bool )( _b > 0 ) );
|
|
|
|
if ( _GC->GetWindingRule() )
|
|
LNK->GetInc() ? _b++ : _b--;
|
|
else //ALTERNATE
|
|
{
|
|
if ( _b )
|
|
_b = 0;
|
|
else
|
|
_b = 1;
|
|
}
|
|
|
|
LNK->SetLeftB( ( bool )( _b > 0 ) );
|
|
}
|
|
break;
|
|
case GO_RIGHT : if ( LNK->Group() == GROUP_A )
|
|
{
|
|
LNK->SetLeftA( ( bool )( _a > 0 ) );
|
|
|
|
if ( _GC->GetWindingRule() )
|
|
LNK->GetInc() ? _a++ : _a--;
|
|
else
|
|
{ //ALTERNATE
|
|
if ( _a )
|
|
_a = 0;
|
|
else
|
|
_a = 1;
|
|
}
|
|
|
|
LNK->SetRightA( ( bool )( _a > 0 ) );
|
|
LNK->SetLeftB( ( bool )( _b > 0 ) );
|
|
LNK->SetRightB( ( bool )( _b > 0 ) );
|
|
}
|
|
else
|
|
{
|
|
LNK->SetRightA( ( bool )( _a > 0 ) );
|
|
LNK->SetLeftA( ( bool )( _a > 0 ) );
|
|
LNK->SetLeftB( ( bool )( _b > 0 ) );
|
|
|
|
if ( _GC->GetWindingRule() )
|
|
LNK->GetInc() ? _b++ : _b--;
|
|
else
|
|
{ //ALTERNATE
|
|
if ( _b )
|
|
_b = 0;
|
|
else
|
|
_b = 1;
|
|
}
|
|
|
|
LNK->SetRightB( ( bool )( _b > 0 ) );
|
|
}
|
|
break;
|
|
default : _GC->error( "Undefined Direction of link", "function IScanBeam::Calc_Set_Left_Right()" );
|
|
break;
|
|
}
|
|
|
|
//THE NEXT WILL WORK for MOST windingrule polygons,
|
|
//even when not taking into acount windingrule
|
|
// not all
|
|
/*
|
|
switch (_dir&1)
|
|
{
|
|
case GO_LEFT : if (LNK->Group() == GROUP_A)
|
|
{
|
|
LNK->SetRightA((bool)(_a>0));
|
|
|
|
if (booleng->Get_WindingRule())
|
|
LNK->GetInc() ? _a++ : _a--;
|
|
else
|
|
_a--;
|
|
|
|
LNK->SetLeftA((bool)(_a>0));
|
|
LNK->SetLeftB((bool)(_b>0));
|
|
LNK->SetRightB((bool)(_b>0));
|
|
}
|
|
else
|
|
{
|
|
LNK->SetRightA((bool)(_a > 0));
|
|
LNK->SetLeftA((bool)(_a>0));
|
|
LNK->SetRightB((bool)(_b>0));
|
|
|
|
if (booleng->Get_WindingRule())
|
|
LNK->GetInc() ? _b++ : _b--;
|
|
else
|
|
_b--;
|
|
|
|
LNK->SetLeftB((bool)(_b>0));
|
|
}
|
|
break;
|
|
case GO_RIGHT : if (LNK->Group() == GROUP_A)
|
|
{
|
|
LNK->SetLeftA((bool)(_a>0));
|
|
|
|
if (booleng->Get_WindingRule())
|
|
LNK->GetInc() ? _a++ : _a--;
|
|
else
|
|
_a++;
|
|
|
|
LNK->SetRightA((bool)(_a>0));
|
|
LNK->SetLeftB((bool)(_b>0));
|
|
LNK->SetRightB((bool)(_b>0));
|
|
}
|
|
else
|
|
{
|
|
LNK->SetRightA((bool)(_a>0));
|
|
LNK->SetLeftA((bool)(_a>0));
|
|
LNK->SetLeftB((bool)(_b>0));
|
|
|
|
if (booleng->Get_WindingRule())
|
|
LNK->GetInc() ? _b++ : _b--;
|
|
else
|
|
_b++;
|
|
|
|
LNK->SetRightB((bool)(_b>0));
|
|
}
|
|
break;
|
|
default : _messagehandler->error("Undefined Direction of link","function IScanBeam::Calc_Set_Left_Right()");
|
|
break;
|
|
}
|
|
*/
|
|
//if the records are parallel (same begin/endnodes)
|
|
//the above link a/b flag are adjusted to the current a/b depth
|
|
if ( record_above_me && Equal( record_above_me ) )
|
|
{
|
|
par = true;
|
|
LNK->Mark();
|
|
record_above_me->_a = _a;
|
|
record_above_me->_b = _b;
|
|
if ( Direction() == GO_LEFT )
|
|
{
|
|
//set the bottom side of the above link
|
|
if ( record_above_me->Direction() == GO_LEFT )
|
|
{
|
|
record_above_me->LNK->SetLeftA( LNK->GetLeftA() );
|
|
record_above_me->LNK->SetLeftB( LNK->GetLeftB() );
|
|
}
|
|
else
|
|
{
|
|
record_above_me->LNK->SetRightA( LNK->GetLeftA() );
|
|
record_above_me->LNK->SetRightB( LNK->GetLeftB() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//set the bottom side of the above link
|
|
if ( record_above_me->Direction() == GO_LEFT )
|
|
{
|
|
record_above_me->LNK->SetLeftA( LNK->GetRightA() );
|
|
record_above_me->LNK->SetLeftB( LNK->GetRightB() );
|
|
}
|
|
else
|
|
{
|
|
record_above_me->LNK->SetRightA( LNK->GetRightA() );
|
|
record_above_me->LNK->SetRightB( LNK->GetRightB() );
|
|
}
|
|
}
|
|
}
|
|
return par;
|
|
}
|
|
|
|
bool Record::Equal( Record *a )
|
|
{
|
|
return( ( bool )( ( LNK->GetOther( a->LNK->GetBeginNode() ) == a->LNK->GetEndNode() ) &&
|
|
( LNK->GetOther( a->LNK->GetEndNode() ) == a->LNK->GetBeginNode() ) ) );
|
|
}
|
|
|
|
|
|
KBoolLine* Record::GetLine()
|
|
{
|
|
return & _line;
|
|
}
|
|
|
|
|