1 /*! \file kbool/src/record.cpp 2 \author Klaas Holwerda or Julian Smart 3 4 Copyright: 2001-2004 (C) Klaas Holwerda 5 6 Licence: see kboollicense.txt 7 8 RCS-ID: $Id: record.cpp,v 1.5 2005/05/24 19:13:39 titato Exp $ 9 */ 10 11 #ifdef __GNUG__ 12 #pragma implementation 13 #endif 14 15 #include "kbool/include/booleng.h" 16 #include "kbool/include/record.h" 17 #include "kbool/include/node.h" 18 19 #include <stdlib.h> 20 #include <math.h> 21 22 #define LNK _line.GetLink() 23 24 //int r_index=-1; 25 //void* _Record_Pool[30]; 26 27 //void DeleteRecordPool() 28 //{ 29 // while (r_index!=-1) 30 // { 31 // free( _Record_Pool[r_index--]); 32 // } 33 //} 34 ~Record()35Record::~Record() 36 { 37 } 38 39 40 //void* Record::operator new(size_t size) 41 //{ 42 // 43 // if (r_index!=-1) 44 // { 45 // return _Record_Pool[r_index--]; 46 // } 47 // 48 // return malloc(size); 49 //} 50 51 //void Record::operator delete(void* recordptr) 52 //{ 53 // 54 // if (r_index < 28) 55 // { 56 // _Record_Pool[++r_index]= recordptr; 57 // return; 58 // } 59 // 60 // free (recordptr); 61 //} 62 63 //void Record::deletepool() 64 //{ 65 // 66 // while (r_index!=-1) 67 // { 68 // free( _Record_Pool[r_index--]); 69 // } 70 //} 71 Record(KBoolLink * link,Bool_Engine * GC)72Record::Record(KBoolLink* link,Bool_Engine* GC) 73 :_line(GC) 74 { 75 _GC=GC; 76 _dir=GO_RIGHT; 77 _a=0; 78 _b=0; 79 _line.Set(link); 80 _line.CalculateLineParameters(); 81 } 82 83 84 //when the dimensions of a link for a record changes, its line parameters need to be recalculated SetNewLink(KBoolLink * link)85void Record::SetNewLink(KBoolLink* link) 86 { 87 _line.Set(link); 88 _line.CalculateLineParameters(); 89 } 90 91 //for beams calculate the ysp on the low scanline Calc_Ysp(Node * low)92void Record::Calc_Ysp(Node* low) 93 { 94 if ((LNK->GetEndNode() == low) || (LNK->GetBeginNode() == low)) 95 { 96 _ysp=low->GetY(); 97 return; 98 } 99 100 if (LNK->GetEndNode()->GetX() == LNK->GetBeginNode()->GetX()) 101 _ysp=low->GetY(); //flatlink only in flatbeams 102 else if (LNK->GetEndNode()->GetX() == low->GetX()) 103 _ysp=LNK->GetEndNode()->GetY(); 104 else if (LNK->GetBeginNode()->GetX() == low->GetX()) 105 _ysp=LNK->GetBeginNode()->GetY(); 106 else 107 _ysp=_line.Calculate_Y_from_X(low->GetX()); 108 } 109 110 //to set the _dir for new links in the beam Set_Flags()111void Record::Set_Flags() 112 { 113 if (LNK->GetEndNode()->GetX()==LNK->GetBeginNode()->GetX()) //flatlink ? 114 { //only happens in flat beams 115 if (LNK->GetEndNode()->GetY() < LNK->GetBeginNode()->GetY()) 116 _dir=GO_RIGHT; 117 else 118 _dir=GO_LEFT; 119 } 120 else 121 { 122 if (LNK->GetEndNode()->GetX() > LNK->GetBeginNode()->GetX()) 123 _dir=GO_RIGHT; 124 else 125 _dir=GO_LEFT; 126 } 127 } 128 GetLink()129KBoolLink* Record::GetLink() 130 { 131 return LNK; 132 } 133 Ysp()134B_INT Record::Ysp() 135 { 136 return _ysp; 137 } 138 SetYsp(B_INT ysp)139void Record::SetYsp(B_INT ysp) 140 { 141 _ysp=ysp; 142 } 143 Direction()144DIRECTION Record::Direction() 145 { 146 return DIRECTION(_dir); 147 } 148 Calc_Left_Right(Record * record_above_me)149bool Record::Calc_Left_Right(Record* record_above_me) 150 { 151 bool par=false; 152 153 if (!record_above_me) //null if no record above 154 { _a=0;_b=0; } 155 else 156 { 157 _a=record_above_me->_a; 158 _b=record_above_me->_b; 159 } 160 161 switch (_dir&1) 162 { 163 case GO_LEFT : if (LNK->Group() == GROUP_A) 164 { 165 LNK->SetRightA((bool)(_a>0)); 166 167 if (_GC->GetWindingRule()) 168 LNK->GetInc() ? _a++ : _a--; 169 else 170 { //ALTERNATE 171 if (_a) 172 _a=0; 173 else 174 _a=1; 175 } 176 177 LNK->SetLeftA((bool)(_a>0)); 178 LNK->SetLeftB((bool)(_b>0)); 179 LNK->SetRightB((bool)(_b>0)); 180 } 181 else 182 { 183 LNK->SetRightA((bool)(_a > 0)); 184 LNK->SetLeftA((bool)(_a>0)); 185 LNK->SetRightB((bool)(_b>0)); 186 187 if (_GC->GetWindingRule()) 188 LNK->GetInc() ? _b++ : _b--; 189 else //ALTERNATE 190 { 191 if (_b) 192 _b=0; 193 else 194 _b=1; 195 } 196 197 LNK->SetLeftB((bool)(_b>0)); 198 } 199 break; 200 case GO_RIGHT : if (LNK->Group() == GROUP_A) 201 { 202 LNK->SetLeftA((bool)(_a>0)); 203 204 if (_GC->GetWindingRule()) 205 LNK->GetInc() ? _a++ : _a--; 206 else 207 { //ALTERNATE 208 if (_a) 209 _a=0; 210 else 211 _a=1; 212 } 213 214 LNK->SetRightA((bool)(_a>0)); 215 LNK->SetLeftB((bool)(_b>0)); 216 LNK->SetRightB((bool)(_b>0)); 217 } 218 else 219 { 220 LNK->SetRightA((bool)(_a>0)); 221 LNK->SetLeftA((bool)(_a>0)); 222 LNK->SetLeftB((bool)(_b>0)); 223 224 if (_GC->GetWindingRule()) 225 LNK->GetInc() ? _b++ : _b--; 226 else 227 { //ALTERNATE 228 if (_b) 229 _b=0; 230 else 231 _b=1; 232 } 233 234 LNK->SetRightB((bool)(_b>0)); 235 } 236 break; 237 default : _GC->error("Undefined Direction of link","function IScanBeam::Calc_Set_Left_Right()"); 238 break; 239 } 240 241 //THE NEXT WILL WORK for MOST windingrule polygons, 242 //even when not taking into acount windingrule 243 // not all 244 /* 245 switch (_dir&1) 246 { 247 case GO_LEFT : if (LNK->Group() == GROUP_A) 248 { 249 LNK->SetRightA((bool)(_a>0)); 250 251 if (booleng->Get_WindingRule()) 252 LNK->GetInc() ? _a++ : _a--; 253 else 254 _a--; 255 256 LNK->SetLeftA((bool)(_a>0)); 257 LNK->SetLeftB((bool)(_b>0)); 258 LNK->SetRightB((bool)(_b>0)); 259 } 260 else 261 { 262 LNK->SetRightA((bool)(_a > 0)); 263 LNK->SetLeftA((bool)(_a>0)); 264 LNK->SetRightB((bool)(_b>0)); 265 266 if (booleng->Get_WindingRule()) 267 LNK->GetInc() ? _b++ : _b--; 268 else 269 _b--; 270 271 LNK->SetLeftB((bool)(_b>0)); 272 } 273 break; 274 case GO_RIGHT : if (LNK->Group() == GROUP_A) 275 { 276 LNK->SetLeftA((bool)(_a>0)); 277 278 if (booleng->Get_WindingRule()) 279 LNK->GetInc() ? _a++ : _a--; 280 else 281 _a++; 282 283 LNK->SetRightA((bool)(_a>0)); 284 LNK->SetLeftB((bool)(_b>0)); 285 LNK->SetRightB((bool)(_b>0)); 286 } 287 else 288 { 289 LNK->SetRightA((bool)(_a>0)); 290 LNK->SetLeftA((bool)(_a>0)); 291 LNK->SetLeftB((bool)(_b>0)); 292 293 if (booleng->Get_WindingRule()) 294 LNK->GetInc() ? _b++ : _b--; 295 else 296 _b++; 297 298 LNK->SetRightB((bool)(_b>0)); 299 } 300 break; 301 default : _messagehandler->error("Undefined Direction of link","function IScanBeam::Calc_Set_Left_Right()"); 302 break; 303 } 304 */ 305 //if the records are parallel (same begin/endnodes) 306 //the above link a/b flag are adjusted to the current a/b depth 307 if (record_above_me && Equal(record_above_me)) 308 { 309 par=true; 310 LNK->Mark(); 311 record_above_me->_a=_a; 312 record_above_me->_b=_b; 313 if (Direction()== GO_LEFT) 314 { 315 //set the bottom side of the above link 316 if (record_above_me->Direction()== GO_LEFT) 317 { 318 record_above_me->LNK->SetLeftA(LNK->GetLeftA()); 319 record_above_me->LNK->SetLeftB(LNK->GetLeftB()); 320 } 321 else 322 { 323 record_above_me->LNK->SetRightA(LNK->GetLeftA()); 324 record_above_me->LNK->SetRightB(LNK->GetLeftB()); 325 } 326 } 327 else 328 { 329 //set the bottom side of the above link 330 if (record_above_me->Direction()== GO_LEFT) 331 { 332 record_above_me->LNK->SetLeftA(LNK->GetRightA()); 333 record_above_me->LNK->SetLeftB(LNK->GetRightB()); 334 } 335 else 336 { 337 record_above_me->LNK->SetRightA(LNK->GetRightA()); 338 record_above_me->LNK->SetRightB(LNK->GetRightB()); 339 } 340 } 341 } 342 return par; 343 } 344 Equal(Record * a)345bool Record::Equal(Record *a) 346 { 347 return((bool)( ( LNK->GetOther(a->LNK->GetBeginNode()) == a->LNK->GetEndNode()) && 348 ( LNK->GetOther(a->LNK->GetEndNode()) == a->LNK->GetBeginNode()) )); 349 } 350 351 GetLine()352KBoolLine* Record::GetLine() 353 { 354 return &_line; 355 } 356 357 358