GME
13
|
00001 // AutoRouterGraph.cpp : Implementation of CAutoRouterGraph 00002 00003 #include "stdafx.h" 00004 #include "AutoRouterGraph.h" 00005 #include "AutoRouterBox.h" 00006 #include "AutoRouterPort.h" 00007 #include "AutoRouterPath.h" 00008 #include "AutoRouterEdge.h" 00009 00010 00011 // --- CAutoRouterGraph 00012 00013 CAutoRouterGraph::CAutoRouterGraph(): 00014 horizontal(true), 00015 vertical(false) 00016 { 00017 horizontal.SetOwner(this); 00018 vertical.SetOwner(this); 00019 00020 CalculateSelfPoints(); 00021 AddSelfEdges(); 00022 } 00023 00024 // --- Boxes 00025 00026 void CAutoRouterGraph::Remove(CAutoRouterBox* box) 00027 { 00028 DeleteBoxAndPortEdges(box); 00029 00030 std::vector<CAutoRouterPath*>::iterator iter; 00031 iter = paths.begin(); 00032 00033 while(iter != paths.end()) 00034 { 00035 bool iteratorChanged = false; 00036 00037 CAutoRouterPath* path = *iter; 00038 00039 CAutoRouterPort* startPort = path->GetStartPort(); 00040 ASSERT(startPort != NULL); 00041 CAutoRouterBox* startbox = startPort->GetOwner(); 00042 00043 CAutoRouterPort* endPort = path->GetEndPort(); 00044 ASSERT(endPort != NULL); 00045 CAutoRouterBox* endbox = endPort->GetOwner(); 00046 00047 if( (startbox == box || endbox == box) ) 00048 { 00049 //DeletePath: 00050 if (path->HasOwner()) 00051 { 00052 DeleteEdges(path); 00053 path->SetOwner(NULL); 00054 00055 iter = paths.erase(iter); 00056 iteratorChanged = true; 00057 } 00058 00059 path->Destroy(); // ?? 00060 } 00061 00062 if (!iteratorChanged) 00063 ++iter; 00064 } 00065 00066 box->SetOwner(NULL); 00067 00068 std::vector<CAutoRouterBox*>::iterator iter2 = std::find(boxes.begin(), boxes.end(), box); 00069 00070 if (iter2 != boxes.end()) 00071 { 00072 boxes.erase(iter2); 00073 } 00074 else 00075 { 00076 //error 00077 ASSERT(false); 00078 } 00079 } 00080 00081 void CAutoRouterGraph::DeleteAllBoxes() 00082 { 00083 for (CAutoRouterBoxList::size_type i = 0; i < boxes.size(); i++) 00084 { 00085 //DeleteBoxAndPortEdges(boxes[i]); // no need: there's a DeleteAllEdges in DeleteAll 00086 boxes[i]->Destroy(); 00087 delete boxes[i]; 00088 } 00089 00090 boxes.clear(); 00091 } 00092 00093 CAutoRouterBox* CAutoRouterGraph::GetBoxAt(const CPoint& point, int nearness) const 00094 { 00095 std::vector<CAutoRouterBox*>::const_iterator iter = boxes.begin(); 00096 while (iter != boxes.end()) 00097 { 00098 if ((*iter)->IsBoxAt(point, nearness)) 00099 return (*iter); 00100 00101 ++iter; 00102 } 00103 00104 return NULL; 00105 } 00106 00107 void CAutoRouterGraph::SetPortAttr(CAutoRouterPort* port, unsigned int attr) 00108 { 00109 DisconnectPathsFrom(port); 00110 port->SetAttributes(attr); 00111 } 00112 00113 bool CAutoRouterGraph::IsRectClipBoxes(const CRect& rect) const 00114 { 00115 for (CAutoRouterBoxList::size_type i = 0; i < boxes.size(); i++) 00116 { 00117 const CRect boxRect = boxes[i]->GetRect(); 00118 if( IsRectClip(rect, boxRect) ) 00119 return true; 00120 } 00121 return false; 00122 } 00123 00124 bool CAutoRouterGraph::IsLineClipBoxes(const CPoint& p1, const CPoint& p2) const 00125 { 00126 CRect rect(p1, p2); 00127 rect.NormalizeRect(); 00128 ASSERT( rect.left == rect.right || rect.top == rect.bottom ); 00129 00130 if( rect.left == rect.right) 00131 rect.right++; 00132 if( rect.top == rect.bottom ) 00133 rect.bottom++; 00134 00135 return IsRectClipBoxes(rect); 00136 } 00137 00138 bool CAutoRouterGraph::CanBoxAt(const CRect& rect) const 00139 { 00140 return !IsRectClipBoxes(InflatedRect(rect, 1)); 00141 } 00142 00143 void CAutoRouterGraph::Add(CAutoRouterPath* path) 00144 { 00145 ASSERT( path != NULL ); 00146 ASSERT(!path->HasOwner()); 00147 00148 path->SetOwner(this); 00149 00150 paths.push_back(path); 00151 00152 AddEdges(path); 00153 00154 #ifdef _DEBUG 00155 AssertValidPath(path); 00156 #endif 00157 } 00158 00159 void CAutoRouterGraph::Remove(CAutoRouterPath* path) 00160 { 00161 DeleteEdges(path); 00162 00163 path->SetOwner(NULL); 00164 00165 std::vector<CAutoRouterPath*>::iterator iter = std::find(paths.begin(), paths.end(), path); 00166 00167 if (iter != paths.end()) 00168 { 00169 paths.erase(iter); 00170 } 00171 else 00172 { 00173 //error 00174 ASSERT(false); 00175 } 00176 } 00177 00178 void CAutoRouterGraph::DeleteAllPaths() 00179 { 00180 std::vector<CAutoRouterPath*>::iterator iter; 00181 iter = paths.begin(); 00182 00183 while (iter != paths.end()) 00184 { 00185 //DeleteEdges(*iter); // no need: there's a DeleteAllEdges in DeleteAll 00186 00187 (*iter)->SetOwner(NULL); 00188 (*iter)->Destroy(); 00189 delete (*iter); 00190 ++iter; 00191 } 00192 00193 paths.clear(); 00194 } 00195 00196 CAutoRouterEdge* CAutoRouterGraph::GetListEdgeAt(const CPoint& point, int nearness) const 00197 { 00198 CAutoRouterEdge* edge; 00199 00200 edge = horizontal.GetEdgeAt(point, nearness); 00201 if( edge ) 00202 return edge; 00203 00204 return vertical.GetEdgeAt(point, nearness); 00205 } 00206 00207 // --- Boxes && Paths 00208 00209 CRect CAutoRouterGraph::GetSurroundRect(void) const 00210 { 00211 CRect rect(0,0,0,0); 00212 00213 for (CAutoRouterBoxList::size_type i = 0; i < boxes.size(); i++) 00214 { 00215 rect |= boxes[i]->GetRect(); 00216 } 00217 00218 for (CAutoRouterPathList::size_type i = 0; i < paths.size(); i++) 00219 { 00220 rect |= paths[i]->GetSurroundRect(); 00221 } 00222 00223 return rect; 00224 } 00225 00226 CAutoRouterBox* CAutoRouterGraph::GetOutOfBox(CPoint& point, RoutingDirection dir) const 00227 { 00228 ASSERT( IsRightAngle(dir) ); 00229 00230 CAutoRouterBox* boxby = NULL; 00231 00232 std::vector<CAutoRouterBox*>::const_iterator iter = boxes.begin(); 00233 00234 while (iter != boxes.end()) 00235 { 00236 const CRect boxRect = (*iter)->GetRect(); 00237 if( boxRect.PtInRect(point) ) 00238 { 00239 boxby = *iter; 00240 iter = boxes.begin(); 00241 00242 GetPointCoord(point, dir) = GetRectOuterCoord(boxRect, dir); 00243 } 00244 ++iter; 00245 } 00246 00247 return boxby; 00248 } 00249 00250 CAutoRouterBox* CAutoRouterGraph::GoToNextBox(CPoint& point, RoutingDirection dir, long stophere) const 00251 { 00252 ASSERT( IsRightAngle(dir) ); 00253 ASSERT( GetPointCoord(point, dir) != stophere ); 00254 00255 CAutoRouterBox* boxby = NULL; 00256 00257 std::vector<CAutoRouterBox*>::const_iterator iter = boxes.begin(); 00258 00259 while (iter != boxes.end()) 00260 { 00261 const CRect boxRect = (*iter)->GetRect(); 00262 if( IsPointInDirFrom(point, boxRect, ReverseDir(dir)) && 00263 IsPointBetweenSides(point, boxRect, dir) && 00264 IsCoordInDirFrom(stophere, GetRectOuterCoord(boxRect, ReverseDir(dir)), dir) ) 00265 { 00266 stophere = GetRectOuterCoord(boxRect, ReverseDir(dir)); 00267 boxby = *iter; 00268 } 00269 ++iter; 00270 } 00271 00272 GetPointCoord(point, dir) = stophere; 00273 00274 return boxby; 00275 } 00276 00277 void CAutoRouterGraph::GetLimitsOfEdge(const CPoint& startPt, const CPoint& endPt, long& min, long& max) const 00278 { 00279 long t; 00280 CPoint start = startPt; 00281 CPoint end = endPt; 00282 00283 std::vector<CAutoRouterBox*>::const_iterator iter = boxes.begin(); 00284 00285 if( start.y == end.y ) 00286 { 00287 if( start.x > end.x ) 00288 { 00289 t = start.x; 00290 start.x = end.x; 00291 end.x = t; 00292 } 00293 00294 while( iter != boxes.end()) 00295 { 00296 const CRect rect = (*iter)->GetRect(); 00297 ++iter; 00298 00299 if(start.x < rect.right && rect.left <= end.x) 00300 { 00301 if( rect.bottom <= start.y && rect.bottom > min ) 00302 min = rect.bottom; 00303 if( rect.top > start.y && rect.top < max ) 00304 max = rect.top; 00305 } 00306 } 00307 } 00308 else 00309 { 00310 ASSERT( start.x == end.x ); 00311 00312 if( start.y > end.y ) 00313 { 00314 t = start.y; 00315 start.y = end.y; 00316 end.y = t; 00317 } 00318 00319 while( iter != boxes.end()) 00320 { 00321 const CRect rect = (*iter)->GetRect(); 00322 ++iter; 00323 00324 if(start.y < rect.bottom && rect.top <= end.y) 00325 { 00326 if( rect.right <= start.x && rect.right > min ) 00327 min = rect.right; 00328 if( rect.left > start.x && rect.left < max ) 00329 max = rect.left; 00330 } 00331 } 00332 } 00333 00334 max--; 00335 } 00336 00337 bool CAutoRouterGraph::Connect(CAutoRouterPath* path) 00338 { 00339 CAutoRouterPort* startport = path->GetStartPort(); 00340 CAutoRouterPort* endport = path->GetEndPort(); 00341 00342 RoutingDirection startdir = path->GetStartDir(); 00343 bool startportHasLimited = false; 00344 bool startportCanHave = true; 00345 if (startdir != Dir_None) { 00346 startportHasLimited = startport->HasLimitedDirs(); 00347 startportCanHave = startport->CanHaveStartEndPointOn(startdir, true); 00348 } 00349 if( startdir == Dir_None || // recalc startdir if empty 00350 startportHasLimited && !startportCanHave) // or is limited and userpref is invalid 00351 { 00352 startdir = startport->GetStartEndDirTo(endport->GetCenter(), true); 00353 } 00354 00355 RoutingDirection enddir = path->GetEndDir(); 00356 bool endportHasLimited = false; 00357 bool endportCanHave = true; 00358 if (enddir != Dir_None) { 00359 endportHasLimited = endport->HasLimitedDirs(); 00360 endportCanHave = endport->CanHaveStartEndPointOn(enddir, false); 00361 } 00362 if( enddir == Dir_None || // like above 00363 endportHasLimited && !endportCanHave) 00364 { 00365 enddir = endport->GetStartEndDirTo(startport->GetCenter(), false, startport == endport ? startdir : Dir_None ); 00366 } 00367 00368 CPoint startpoint = startport->CreateStartEndPointOn(startdir); 00369 CPoint endpoint = endport->CreateStartEndPointOn(enddir); 00370 00371 if( startpoint == endpoint ) 00372 startpoint = StepOneInDir(startpoint, NextClockwiseDir(startdir)); 00373 00374 return Connect(path, startpoint, endpoint); 00375 } 00376 00377 bool CAutoRouterGraph::Connect(CAutoRouterPath* path, CPoint& startpoint, CPoint& endpoint) 00378 { 00379 ASSERT( path != NULL && path->GetOwner() == this ); 00380 ASSERT( !path->IsConnected() ); 00381 ASSERT( startpoint != endpoint ); 00382 00383 CAutoRouterPort* startPort = path->GetStartPort(); 00384 ASSERT(startPort != NULL); 00385 RoutingDirection startdir = startPort->OnWhichEdge(startpoint); 00386 00387 CAutoRouterPort* endPort = path->GetEndPort(); 00388 ASSERT(endPort != NULL); 00389 RoutingDirection enddir = endPort->OnWhichEdge(endpoint); 00390 ASSERT( IsRightAngle(startdir) && IsRightAngle(enddir) ); 00391 00392 CPoint start = startpoint; 00393 GetOutOfBox(start, startdir); 00394 ASSERT( start != startpoint ); 00395 00396 CPoint end = endpoint; 00397 GetOutOfBox(end, enddir); 00398 ASSERT( end != endpoint ); 00399 00400 ASSERT( path->IsEmpty() ); 00401 00402 CPointListPath ret; 00403 bool isAutoRouted = path->IsAutoRouted(); 00404 if (isAutoRouted) 00405 ConnectPoints(ret, start, end, startdir, enddir); 00406 00407 if (!isAutoRouted) 00408 { 00409 CPointListPath ret2; 00410 path->ApplyCustomizationsBeforeAutoConnectPoints(ret2); 00411 00412 if (ret2.GetCount() > 0) 00413 { 00414 ret.RemoveAll(); 00415 POSITION pos = ret2.GetHeadPosition(); 00416 while( pos != NULL ) 00417 { 00418 ret.AddTail(ret2.GetNext(pos)); 00419 } 00420 } 00421 } 00422 00423 path->DeleteAll(); 00424 00425 path->AddTail(startpoint); 00426 POSITION pos = ret.GetHeadPosition(); 00427 while( pos != NULL ) 00428 { 00429 CPoint p = ret.GetNext(pos); 00430 path->AddTail(p); 00431 } 00432 path->AddTail(endpoint); 00433 00434 if (isAutoRouted) { 00435 path->SimplifyTrivially(); 00436 SimplifyPathPoints(path); 00437 CenterStairsInPathPoints(path, startdir, enddir); 00438 } 00439 path->SetState(ARPATHST_Connected); 00440 00441 // Apply custom edge modifications - step 1 00442 // (Step 1: Move the desired edges - see in CAutoRouterGraph::Connect(CAutoRouterPath* path, CPoint& startpoint, CPoint& endpoint) 00443 // Step 2: Fix the desired edges - see in CAutoRouterEdgeList::AddEdges(CAutoRouterPath* path)) 00444 if (isAutoRouted) 00445 path->ApplyCustomizationsAfterAutoConnectPointsAndStuff(); 00446 00447 return AddEdges(path); 00448 } 00449 00450 void CAutoRouterGraph::ConnectPoints(CPointListPath& ret, CPoint& start, CPoint& end, RoutingDirection hintstartdir, RoutingDirection hintenddir) 00451 { 00452 ASSERT( ret.IsEmpty() ); 00453 00454 CPoint& thestart = start; 00455 POSITION retend = NULL; 00456 00457 while( start != end ) 00458 { 00459 RoutingDirection dir1 = ExGetMajorDir(end-start); 00460 RoutingDirection dir2 = ExGetMinorDir(end-start); 00461 ASSERT( dir1 != Dir_None ); 00462 00463 ASSERT( dir1 == GetMajorDir(end-start) ); 00464 ASSERT( dir2 == Dir_None || dir2 == GetMinorDir(end-start) ); 00465 00466 if( retend == NULL && dir2 == hintstartdir && dir2 != Dir_None ) 00467 { 00468 // i.e. std::swap(dir1, dir2); 00469 dir2 = dir1; 00470 dir1 = hintstartdir; 00471 } 00472 00473 if (retend == NULL) 00474 retend = ret.AddTail(start); 00475 else 00476 retend = ret.InsertAfter(retend, start); 00477 CPoint old = start; 00478 00479 CAutoRouterBox* box = GoToNextBox(start, dir1, end); 00480 if( start == old ) 00481 { 00482 ASSERT( box != NULL ); 00483 const CRect rect = box->GetRect(); 00484 00485 if( dir2 == Dir_None ) 00486 dir2 = NextClockwiseDir(dir1); 00487 00488 ASSERT( dir1 != dir2 && dir1 != Dir_None && dir2 != Dir_None ); 00489 00490 if( IsPointInDirFrom(end, rect, dir2) ) 00491 { 00492 ASSERT( !IsPointInDirFrom(start, rect, dir2) ); 00493 GoToNextBox(start, dir2, end); 00494 // this assert fails if two boxes are adjacent, and a connection wants to go between 00495 ASSERT( IsPointInDirFrom(start, rect, dir2) ); 00496 } 00497 else 00498 { 00499 ASSERT( IsPointBetweenSides(end, rect, dir1) ); 00500 ASSERT( !IsPointIn(end, rect) ); 00501 00502 int rev = 0; 00503 00504 if( ReverseDir(dir2) == hintenddir ) 00505 rev = 1; 00506 else if( dir2 != hintenddir ) 00507 { 00508 if( IsPointBetweenSides(thestart, rect, dir1) ) 00509 { 00510 if( IsPointInDirFrom(rect.TopLeft() + rect.BottomRight(), start + end, dir2) ) 00511 rev = 1; 00512 } 00513 else 00514 if( IsPointInDirFrom(start, thestart, dir2) ) 00515 rev = 1; 00516 } 00517 00518 if( rev ) 00519 { 00520 dir2 = ReverseDir(dir2); 00521 } 00522 00523 GetPointCoord(start, dir2) = GetRectOuterCoord(rect, dir2); 00524 00525 ASSERT( start != old ); 00526 ASSERT(retend != NULL); 00527 retend = ret.InsertAfter(retend, start); 00528 00529 old = start; 00530 00531 GetPointCoord(start, dir1) = GetRectOuterCoord(rect, dir1); 00532 ASSERT( IsPointInDirFrom(end, start, dir1) ); 00533 if( GetPointCoord(start, dir1) != GetPointCoord(end, dir1) ) 00534 GoToNextBox(start, dir1, end); 00535 } 00536 00537 ASSERT( start != old ); 00538 } 00539 } 00540 00541 ret.AddTail(end); 00542 } 00543 00544 void CAutoRouterGraph::DisconnectAll() 00545 { 00546 std::vector<CAutoRouterPath*>::iterator iter; 00547 iter = paths.begin(); 00548 00549 while(iter != paths.end()) 00550 { 00551 Disconnect(*iter); 00552 ++iter; 00553 } 00554 } 00555 00556 void CAutoRouterGraph::Disconnect(CAutoRouterPath* path) 00557 { 00558 if( path->IsConnected() ) 00559 DeleteEdges(path); 00560 00561 path->DeleteAll(); 00562 } 00563 00564 void CAutoRouterGraph::DisconnectPathsClipping(const CRect& rect) 00565 { 00566 std::vector<CAutoRouterPath*>::reverse_iterator iter; 00567 iter = paths.rbegin(); 00568 00569 while(iter != paths.rend()) 00570 { 00571 if( (*iter)->IsPathClip(rect) ) 00572 Disconnect(*iter); 00573 ++iter; 00574 } 00575 } 00576 00577 void CAutoRouterGraph::DisconnectPathsFrom(CAutoRouterBox* box) 00578 { 00579 std::vector<CAutoRouterPath*>::reverse_iterator iter; 00580 iter = paths.rbegin(); 00581 00582 while(iter != paths.rend()) 00583 { 00584 CAutoRouterPath* path = *iter; 00585 00586 CAutoRouterPort* startPort = path->GetStartPort(); 00587 ASSERT(startPort != NULL); 00588 CAutoRouterBox* startbox = startPort->GetOwner(); 00589 ASSERT(startbox != NULL); 00590 00591 CAutoRouterPort* endPort = path->GetEndPort(); 00592 ASSERT(endPort != NULL); 00593 CAutoRouterBox* endbox = endPort->GetOwner(); 00594 ASSERT(endbox != NULL); 00595 00596 if( (startbox == box || endbox == box) ) 00597 Disconnect(path); 00598 00599 ++iter; 00600 } 00601 } 00602 00603 void CAutoRouterGraph::DisconnectPathsFrom(CAutoRouterPort* port) 00604 { 00605 std::vector<CAutoRouterPath*>::reverse_iterator iter; 00606 iter = paths.rbegin(); 00607 00608 while(iter != paths.rend()) 00609 { 00610 CAutoRouterPath* path = *iter; 00611 00612 CAutoRouterPort* startport = path->GetStartPort(); 00613 CAutoRouterPort* endport = path->GetEndPort(); 00614 00615 if( (startport == port || endport == port) ) 00616 Disconnect(path); 00617 00618 ++iter; 00619 } 00620 } 00621 00622 // --- Edges 00623 00624 void CAutoRouterGraph::AddSelfEdges(void) 00625 { 00626 horizontal.AddEdges(this); 00627 vertical.AddEdges(this); 00628 } 00629 00630 void CAutoRouterGraph::AddEdges(CAutoRouterGraph* graph) 00631 { 00632 horizontal.AddEdges(graph); 00633 vertical.AddEdges(graph); 00634 } 00635 00636 void CAutoRouterGraph::AddEdges(CAutoRouterBox* box) 00637 { 00638 horizontal.AddEdges(box); 00639 vertical.AddEdges(box); 00640 } 00641 00642 void CAutoRouterGraph::AddEdges(CAutoRouterPort* port) 00643 { 00644 horizontal.AddEdges(port); 00645 vertical.AddEdges(port); 00646 } 00647 00648 bool CAutoRouterGraph::AddEdges(CAutoRouterPath* path) 00649 { 00650 return horizontal.AddEdges(path) && vertical.AddEdges(path); 00651 } 00652 00653 void CAutoRouterGraph::DeleteEdges(CObject* object) 00654 { 00655 horizontal.DeleteEdges(object); 00656 vertical.DeleteEdges(object); 00657 } 00658 00659 void CAutoRouterGraph::AddAllEdges() 00660 { 00661 ASSERT( horizontal.IsEmpty() && vertical.IsEmpty() ); 00662 00663 std::vector<CAutoRouterBox*>::iterator iter; 00664 iter = boxes.begin(); 00665 00666 while (iter != boxes.end()) 00667 { 00668 AddBoxAndPortEdges(*iter); 00669 ++iter; 00670 } 00671 00672 std::vector<CAutoRouterPath*>::iterator iterP; 00673 iterP = paths.begin(); 00674 00675 while (iterP != paths.end()) 00676 { 00677 AddEdges(*iterP); 00678 iterP++; 00679 } 00680 } 00681 00682 void CAutoRouterGraph::DeleteAllEdges() 00683 { 00684 horizontal.DeleteAllEdges(); 00685 vertical.DeleteAllEdges(); 00686 } 00687 00688 void CAutoRouterGraph::AddBoxAndPortEdges(CAutoRouterBox* box) 00689 { 00690 ASSERT( box != NULL ); 00691 00692 AddEdges(box); 00693 00694 const CAutoRouterPortList& pl = box->GetPortList(); 00695 std::vector<CAutoRouterPort*>::const_iterator ii = pl.begin(); 00696 while( ii != pl.end() ) { 00697 AddEdges(*ii); 00698 ++ii; 00699 } 00700 } 00701 00702 void CAutoRouterGraph::DeleteBoxAndPortEdges(CAutoRouterBox* box) 00703 { 00704 ASSERT( box != NULL ); 00705 00706 DeleteEdges(box); 00707 00708 const CAutoRouterPortList& pl = box->GetPortList(); 00709 std::vector<CAutoRouterPort*>::const_iterator ii = pl.begin(); 00710 while( ii != pl.end() ) { 00711 DeleteEdges(*ii); 00712 ++ii; 00713 } 00714 } 00715 00716 CAutoRouterEdgeList& CAutoRouterGraph::GetEdgeList(bool ishorizontal) 00717 { 00718 return ishorizontal ? horizontal : vertical; 00719 } 00720 00721 // --- Path && Edges 00722 00723 bool CAutoRouterGraph::CanDeleteTwoEdgesAt(CAutoRouterPath* path, CPointListPath& points, POSITION pos) const 00724 { 00725 #ifdef _DEBUG 00726 ASSERT( path->GetOwner() == this ); 00727 path->AssertValid(); 00728 ASSERT( path->IsConnected() ); 00729 points.AssertValidPos(pos); 00730 #ifdef _DEBUG_DEEP 00731 // horizontal.AssertValidPathEdges(path, points); 00732 // vertical.AssertValidPathEdges(path, points); 00733 #endif 00734 #endif 00735 00736 POSITION pointpos = pos; 00737 CPoint point = points.GetNext(pos); 00738 POSITION npointpos = pos; 00739 if( npointpos == NULL ) 00740 return false; 00741 CPoint npoint = points.GetNext(pos); 00742 POSITION nnpointpos = pos; 00743 if( nnpointpos == NULL ) 00744 return false; 00745 00746 pos = pointpos; 00747 points.GetPrev(pos); 00748 POSITION ppointpos = pos; if( ppointpos == NULL ) return false; 00749 CPoint ppoint = points.GetPrev(pos); 00750 POSITION pppointpos = pos; if( pppointpos == NULL ) return false; 00751 if( npoint == point) return false; // direction of zero-length edges can't be determined, so don't delete them 00752 00753 ASSERT( pppointpos != NULL && ppointpos != NULL && pointpos != NULL && npointpos != NULL && nnpointpos != NULL ); 00754 00755 RoutingDirection dir = GetDir(npoint - point); 00756 ASSERT( IsRightAngle(dir) ); 00757 bool ishorizontal = IsHorizontal(dir); 00758 00759 CPoint newpoint; 00760 GetPointCoord(newpoint, ishorizontal) = GetPointCoord(npoint, ishorizontal); 00761 GetPointCoord(newpoint, !ishorizontal) = GetPointCoord(ppoint, !ishorizontal); 00762 00763 ASSERT( GetDir(newpoint - ppoint) == dir ); 00764 00765 if( IsLineClipBoxes(newpoint, npoint) ) return false; 00766 if( IsLineClipBoxes(newpoint, ppoint) ) return false; 00767 00768 return true; 00769 } 00770 00771 void CAutoRouterGraph::DeleteTwoEdgesAt(CAutoRouterPath* path, CPointListPath& points, POSITION pos) 00772 { 00773 #ifdef _DEBUG 00774 ASSERT( path->GetOwner() == this ); 00775 path->AssertValid(); 00776 ASSERT( path->IsConnected() ); 00777 points.AssertValidPos(pos); 00778 #ifdef _DEBUG_DEEP 00779 // horizontal.AssertValidPathEdges(path, points); 00780 // vertical.AssertValidPathEdges(path, points); 00781 #endif 00782 #endif 00783 00784 POSITION pointpos = pos; 00785 CPoint* point = &(points.GetNext(pos)); 00786 POSITION npointpos = pos; 00787 CPoint* npoint = &(points.GetNext(pos)); 00788 POSITION nnpointpos = pos; 00789 CPoint* nnpoint = &(points.GetNext(pos)); 00790 POSITION nnnpointpos = pos; 00791 pos = pointpos; 00792 points.GetPrev(pos); 00793 POSITION ppointpos = pos; 00794 CPoint* ppoint = &(points.GetPrev(pos)); 00795 POSITION pppointpos = pos; 00796 CPoint* pppoint = &(points.GetAt(pos)); 00797 00798 ASSERT( pppointpos != NULL && ppointpos != NULL && pointpos != NULL && npointpos != NULL && nnpointpos != NULL ); 00799 ASSERT( pppoint != NULL && ppoint != NULL && point != NULL && npoint != NULL && nnpoint != NULL ); 00800 00801 RoutingDirection dir = GetDir(*npoint - *point); 00802 ASSERT( IsRightAngle(dir) ); 00803 bool ishorizontal = IsHorizontal(dir); 00804 00805 CPoint newpoint; 00806 GetPointCoord(newpoint, ishorizontal) = GetPointCoord(*npoint, ishorizontal); 00807 GetPointCoord(newpoint, !ishorizontal) = GetPointCoord(*ppoint, !ishorizontal); 00808 00809 ASSERT( GetDir(newpoint - *ppoint) == dir ); 00810 00811 ASSERT( !IsLineClipBoxes(newpoint, *npoint) ); 00812 ASSERT( !IsLineClipBoxes(newpoint, *ppoint) ); 00813 00814 CAutoRouterEdgeList& hlist = GetEdgeList(ishorizontal); 00815 CAutoRouterEdgeList& vlist = GetEdgeList(!ishorizontal); 00816 00817 CAutoRouterEdge* ppedge = hlist.GetEdgeByPointer(pppoint, ppoint); 00818 CAutoRouterEdge* pedge = vlist.GetEdgeByPointer(ppoint, point); 00819 CAutoRouterEdge* nedge = hlist.GetEdgeByPointer(point, npoint); 00820 CAutoRouterEdge* nnedge = vlist.GetEdgeByPointer(npoint, nnpoint); 00821 00822 ASSERT( ppedge != NULL && pedge != NULL && nedge != NULL && nnedge != NULL ); 00823 00824 vlist.Delete(pedge); 00825 hlist.Delete(nedge); 00826 00827 points.RemoveAt(pointpos); 00828 points.RemoveAt(npointpos); 00829 points.SetAt(ppointpos, newpoint); 00830 00831 ASSERT( ppedge->GetEndPoint() == *ppoint && ppedge->GetEndPointNext() == *point ); 00832 ppedge->SetEndPointNext(nnpoint); 00833 00834 ASSERT( nnedge->GetStartPoint() == *npoint && nnedge->GetStartPointPrev() == *point ); 00835 nnedge->SetStartPoint(ppoint); 00836 nnedge->SetStartPointPrev(pppoint); 00837 00838 if( nnnpointpos != NULL ) 00839 { 00840 CAutoRouterEdge* nnnedge = hlist.GetEdgeByPointer(nnpoint, &(points.GetAt(nnnpointpos))); 00841 ASSERT( nnnedge != NULL ); 00842 ASSERT( nnnedge->GetStartPointPrev() == *npoint && nnnedge->GetStartPoint() == *nnpoint ); 00843 nnnedge->SetStartPointPrev(ppoint); 00844 } 00845 00846 if( *nnpoint == newpoint ) 00847 DeleteSamePointsAt(path, points, ppointpos); 00848 00849 #ifdef _DEBUG_DEEP 00850 path->AssertValid(); 00851 horizontal.AssertValidPathEdges(path, points); 00852 vertical.AssertValidPathEdges(path, points); 00853 #endif 00854 } 00855 00856 void CAutoRouterGraph::DeleteSamePointsAt(CAutoRouterPath* path, CPointListPath& points, POSITION pos) 00857 { 00858 #ifdef _DEBUG 00859 ASSERT( path->GetOwner() == this ); 00860 path->AssertValid(); 00861 ASSERT( path->IsConnected() ); 00862 points.AssertValidPos(pos); 00863 #endif 00864 00865 POSITION pointpos = pos; 00866 CPoint* point = &(points.GetNext(pos)); 00867 POSITION npointpos = pos; 00868 CPoint* npoint = &(points.GetNext(pos)); 00869 POSITION nnpointpos = pos; 00870 CPoint* nnpoint = &(points.GetNext(pos)); 00871 POSITION nnnpointpos = pos; 00872 pos = pointpos; 00873 points.GetPrev(pos); 00874 POSITION ppointpos = pos; 00875 CPoint* ppoint = &(points.GetPrev(pos)); 00876 POSITION pppointpos = pos; 00877 CPoint* pppoint = pos == NULL ? NULL : &(points.GetAt(pos)); 00878 00879 ASSERT( ppointpos != NULL && pointpos != NULL && npointpos != NULL && nnpointpos != NULL ); 00880 ASSERT( ppoint != NULL && point != NULL && npoint != NULL && nnpoint != NULL ); 00881 ASSERT( *point == *npoint && *point != *ppoint ); 00882 00883 RoutingDirection dir = GetDir(*point - *ppoint); 00884 ASSERT( IsRightAngle(dir) ); 00885 bool ishorizontal = IsHorizontal(dir); 00886 00887 CAutoRouterEdgeList& hlist = GetEdgeList(ishorizontal); 00888 CAutoRouterEdgeList& vlist = GetEdgeList(!ishorizontal); 00889 00890 CAutoRouterEdge* pedge = hlist.GetEdgeByPointer(ppoint, point); 00891 CAutoRouterEdge* nedge = vlist.GetEdgeByPointer(point, npoint); 00892 CAutoRouterEdge* nnedge = hlist.GetEdgeByPointer(npoint, nnpoint); 00893 00894 ASSERT( pedge != NULL && nedge != NULL && nnedge != NULL ); 00895 00896 vlist.Delete(pedge); 00897 hlist.Delete(nedge); 00898 00899 points.RemoveAt(pointpos); 00900 points.RemoveAt(npointpos); 00901 00902 if( pppointpos != NULL ) 00903 { 00904 CAutoRouterEdge* ppedge = vlist.GetEdgeByPointer(pppoint, ppoint); 00905 ASSERT( ppedge != NULL && ppedge->GetEndPoint() == *ppoint && ppedge->GetEndPointNext() == *point ); 00906 ppedge->SetEndPointNext(nnpoint); 00907 } 00908 00909 ASSERT( nnedge->GetStartPoint() == *npoint && nnedge->GetStartPointPrev() == *point ); 00910 nnedge->SetStartPoint(ppoint); 00911 nnedge->SetStartPointPrev(pppoint); 00912 00913 if( nnnpointpos != NULL ) 00914 { 00915 CAutoRouterEdge* nnnedge = vlist.GetEdgeByPointer(nnpoint, &(points.GetAt(nnnpointpos))); 00916 ASSERT( nnnedge != NULL && nnnedge->GetStartPointPrev() == *npoint && nnnedge->GetStartPoint() == *nnpoint ); 00917 nnnedge->SetStartPointPrev(ppoint); 00918 } 00919 00920 #ifdef _DEBUG_DEEP 00921 path->AssertValid(); 00922 // horizontal.AssertValidPathEdges(path, points); 00923 // vertical.AssertValidPathEdges(path, points); 00924 #endif 00925 } 00926 00927 bool CAutoRouterGraph::SimplifyPaths() 00928 { 00929 bool was = false; 00930 00931 std::vector<CAutoRouterPath*>::iterator iter; 00932 iter = paths.begin(); 00933 00934 while (iter != paths.end()) 00935 { 00936 CAutoRouterPath* path = *iter; 00937 ++iter; 00938 00939 if (path->IsAutoRouted()) { 00940 CPointListPath& pointList = path->GetPointList(); 00941 POSITION pointpos = pointList.GetHeadPosition(); 00942 00943 while( pointpos != NULL ) 00944 { 00945 if( CanDeleteTwoEdgesAt(path, pointList, pointpos) ) 00946 { 00947 DeleteTwoEdgesAt(path, pointList, pointpos); 00948 was = true; 00949 break; 00950 } 00951 pointList.GetNext(pointpos); 00952 } 00953 } 00954 } 00955 00956 return was; 00957 } 00958 00959 void CAutoRouterGraph::CenterStairsInPathPoints(CAutoRouterPath* path, RoutingDirection hintstartdir, RoutingDirection hintenddir) 00960 { 00961 ASSERT( path != NULL ); 00962 ASSERT( !path->IsConnected() ); 00963 00964 CPointListPath& pointList = path->GetPointList(); 00965 ASSERT( pointList.GetCount() >= 2 ); 00966 00967 #ifdef _DEBUG 00968 path->AssertValidPoints(); 00969 #endif 00970 00971 CPoint p1; 00972 CPoint p2; 00973 CPoint p3; 00974 CPoint p4; 00975 00976 POSITION p1p = NULL; 00977 POSITION p2p = NULL; 00978 POSITION p3p = NULL; 00979 POSITION p4p = NULL; 00980 00981 RoutingDirection d12 = Dir_None; 00982 RoutingDirection d23 = Dir_None; 00983 RoutingDirection d34 = Dir_None; 00984 00985 const CPoint outOfBoxStartPoint = path->GetOutOfBoxStartPoint(hintstartdir); 00986 const CPoint outOfBoxEndPoint = path->GetOutOfBoxEndPoint(hintenddir); 00987 00988 POSITION pos = pointList.GetHeadPosition(); 00989 ASSERT( pos != NULL ); 00990 00991 p1p = pos; 00992 p1 = pointList.GetNext(pos); 00993 00994 while( pos != NULL ) 00995 { 00996 p4p = p3p; 00997 p3p = p2p; 00998 p2p = p1p; 00999 p1p = pos; 01000 01001 p4 = p3; 01002 p3 = p2; 01003 p2 = p1; 01004 p1 = pointList.GetNext(pos); 01005 01006 d34 = d23; 01007 d23 = d12; 01008 01009 if( p2p != NULL ) 01010 { 01011 d12 = GetDir(p2 - p1); 01012 #ifdef _DEBUG 01013 ASSERT( IsRightAngle(d12) ); 01014 if( p3p != NULL ) 01015 ASSERT( AreInRightAngle(d12, d23) ); 01016 #endif 01017 } 01018 01019 if( p4p != NULL && d12 == d34 ) 01020 { 01021 ASSERT( p1p != NULL && p2p != NULL && p3p != NULL && p4p != NULL ); 01022 01023 CPoint np2 = p2; 01024 CPoint np3 = p3; 01025 bool h = IsHorizontal(d12); 01026 01027 long p4x = GetPointCoord(p4, h); 01028 long p3x = GetPointCoord(p3, h); 01029 long p1x = GetPointCoord(p1, h); 01030 01031 if( p1x < p4x ) 01032 { 01033 long t = p1x; 01034 p1x = p4x; 01035 p4x = t; 01036 } 01037 01038 if( p4x < p3x && p3x < p1x ) 01039 { 01040 long m = (p4x + p1x)/2; 01041 GetPointCoord(np2, h) = m; 01042 GetPointCoord(np3, h) = m; 01043 01044 GetLimitsOfEdge(np2, np3, p4x, p1x); 01045 01046 m = (p4x + p1x)/2; 01047 GetPointCoord(np2, h) = m; 01048 GetPointCoord(np3, h) = m; 01049 01050 if( !IsLineClipBoxes(np2, np3) && 01051 !IsLineClipBoxes(p1p == pointList.GetTailPosition() ? outOfBoxEndPoint : p1, np2) && 01052 !IsLineClipBoxes(p4p == pointList.GetHeadPosition() ? outOfBoxStartPoint : p4, np3) ) 01053 { 01054 p2 = np2; 01055 p3 = np3; 01056 pointList.SetAt(p2p, p2); 01057 pointList.SetAt(p3p, p3); 01058 } 01059 } 01060 } 01061 } 01062 01063 #ifdef _DEBUG 01064 path->AssertValidPoints(); 01065 #endif 01066 } 01067 01068 void CAutoRouterGraph::SimplifyPathPoints(CAutoRouterPath* path) 01069 { 01070 ASSERT( path != NULL ); 01071 ASSERT( !path->IsConnected() ); 01072 01073 CPointListPath& pointList = path->GetPointList(); 01074 ASSERT( pointList.GetCount() >= 2 ); 01075 01076 #ifdef _DEBUG 01077 path->AssertValidPoints(); 01078 #endif 01079 01080 CPoint p1; 01081 CPoint p2; 01082 CPoint p3; 01083 CPoint p4; 01084 CPoint p5; 01085 01086 POSITION p1p = NULL; 01087 POSITION p2p = NULL; 01088 POSITION p3p = NULL; 01089 POSITION p4p = NULL; 01090 POSITION p5p = NULL; 01091 01092 POSITION pos = pointList.GetHeadPosition(); 01093 ASSERT( pos != NULL ); 01094 01095 p1p = pos; 01096 p1 = pointList.GetNext(pos); 01097 01098 while( pos != NULL ) 01099 { 01100 p5p = p4p; 01101 p4p = p3p; 01102 p3p = p2p; 01103 p2p = p1p; 01104 p1p = pos; 01105 01106 p5 = p4; 01107 p4 = p3; 01108 p3 = p2; 01109 p2 = p1; 01110 p1 = pointList.GetNext(pos); 01111 01112 if( p5p != NULL ) 01113 { 01114 ASSERT( p1p != NULL && p2p != NULL && p3p != NULL && p4p != NULL && p5p != NULL ); 01115 ASSERT( p1 != p2 && p2 != p3 && p3 != p4 && p4 != p5 ); 01116 01117 RoutingDirection d = GetDir(p2 - p1); 01118 ASSERT( IsRightAngle(d) ); 01119 bool h = IsHorizontal(d); 01120 01121 CPoint np3; 01122 GetPointCoord(np3, h) = GetPointCoord(p5, h); 01123 GetPointCoord(np3, !h) = GetPointCoord(p1, !h); 01124 01125 if( !IsLineClipBoxes(p2, np3) && !IsLineClipBoxes(np3, p4) ) 01126 { 01127 pointList.RemoveAt(p2p); 01128 pointList.RemoveAt(p4p); 01129 pointList.SetAt(p3p, np3); 01130 if( np3 == p1 ) 01131 pointList.RemoveAt(p1p); 01132 if( np3 == p5 ) 01133 pointList.RemoveAt(p5p); 01134 01135 p1p = NULL; 01136 p2p = NULL; 01137 p3p = NULL; 01138 p4p = NULL; 01139 01140 pos = pointList.GetHeadPosition(); 01141 } 01142 } 01143 } 01144 01145 #ifdef _DEBUG 01146 path->AssertValidPoints(); 01147 #endif 01148 } 01149 01150 void CAutoRouterGraph::ConnectAllDisconnectedPaths() 01151 { 01152 std::vector<CAutoRouterPath*>::iterator iter; 01153 01154 bool success = false; 01155 bool giveup = false; 01156 while (!success && !giveup) { 01157 success = true; 01158 iter = paths.begin(); 01159 while (iter != paths.end() && success) 01160 { 01161 CAutoRouterPath* path = *iter; 01162 01163 if( !path->IsConnected() ) 01164 { 01165 success = Connect(path); 01166 if (!success) { 01167 // Something is messed up, probably an existing edge customization results in a zero length edge 01168 // In that case we try to delete any customization for this path to recover from the problem 01169 if (path->AreTherePathCustomizations()) 01170 path->RemovePathCustomizations(); 01171 else 01172 giveup = true; 01173 } 01174 } 01175 01176 ++iter; 01177 } 01178 if (!success && !giveup) 01179 DisconnectAll(); // There was an error, delete halfway results to be able to start a new pass 01180 } 01181 } 01182 01183 // --- SelfPoints 01184 01185 void CAutoRouterGraph::CalculateSelfPoints() 01186 { 01187 selfpoints[0].x = ED_MINCOORD; 01188 selfpoints[0].y = ED_MINCOORD; 01189 01190 selfpoints[1].x = ED_MAXCOORD; 01191 selfpoints[1].y = ED_MINCOORD; 01192 01193 selfpoints[2].x = ED_MAXCOORD; 01194 selfpoints[2].y = ED_MAXCOORD; 01195 01196 selfpoints[3].x = ED_MINCOORD; 01197 selfpoints[3].y = ED_MAXCOORD; 01198 } 01199 01200 CAutoRouterBox* CAutoRouterGraph::CreateBox(void) const 01201 { 01202 CAutoRouterBox* box = new CAutoRouterBox(); 01203 ASSERT( box != NULL ); 01204 01205 return box; 01206 } 01207 01208 void CAutoRouterGraph::AddBox(CAutoRouterBox* box) 01209 { 01210 ASSERT(box != NULL); 01211 if (box == NULL) 01212 return; 01213 01214 const CRect rect = box->GetRect(); 01215 01216 DisconnectPathsClipping(rect); 01217 01218 box->SetOwner(this); 01219 01220 boxes.push_back(box); 01221 01222 AddBoxAndPortEdges(box); 01223 } 01224 01225 void CAutoRouterGraph::DeleteBox(CAutoRouterBox* box) 01226 { 01227 ASSERT(box != NULL); 01228 if (box == NULL) 01229 return; 01230 01231 if( box->HasOwner() ) 01232 { 01233 Remove(box); 01234 } 01235 01236 box->Destroy(); 01237 delete box; 01238 } 01239 01240 void CAutoRouterGraph::ShiftBoxBy(CAutoRouterBox* box, const CPoint& offset) 01241 { 01242 ASSERT(box != NULL); 01243 if (box == NULL) 01244 return; 01245 01246 DeleteBoxAndPortEdges(box); 01247 box->ShiftBy(offset); 01248 AddBoxAndPortEdges(box); 01249 01250 const CRect rect = box->GetRect(); 01251 DisconnectPathsClipping(rect); 01252 DisconnectPathsFrom(box); 01253 } 01254 01255 long CAutoRouterGraph::AutoRoute(long aspect) 01256 { 01257 ConnectAllDisconnectedPaths(); 01258 01259 int updated = 0; 01260 int last = 0; 01261 int c = 100; // max # of total op 01262 int dm = 10; // max # of distribution op 01263 int d = 0; 01264 01265 while( c > 0 ) 01266 { 01267 if( c > 0 ) 01268 { 01269 if( last == 1 ) 01270 break; 01271 01272 c--; 01273 if( SimplifyPaths() ) 01274 { 01275 updated = 1; 01276 last = 1; 01277 } 01278 } 01279 01280 if( c > 0 ) 01281 { 01282 if( last == 2 ) 01283 break; 01284 01285 c--; 01286 if( horizontal.Block_ScanBackward() ) 01287 { 01288 updated = 1; 01289 01290 do { 01291 c--; 01292 } while( c > 0 && horizontal.Block_ScanBackward() ); 01293 01294 if( last < 2 || last > 5 ) 01295 d = 0; 01296 else if( ++d >= dm ) 01297 break; 01298 01299 last = 2; 01300 } 01301 } 01302 01303 if( c > 0 ) 01304 { 01305 if( last == 3 ) 01306 break; 01307 01308 c--; 01309 if( horizontal.Block_ScanForward() ) 01310 { 01311 updated = 1; 01312 01313 do { 01314 c--; 01315 } while( c > 0 && horizontal.Block_ScanForward() ); 01316 01317 if( last < 2 || last > 5 ) 01318 d = 0; 01319 else if( ++d >= dm ) 01320 break; 01321 01322 last = 3; 01323 } 01324 } 01325 01326 if( c > 0 ) 01327 { 01328 if( last == 4 ) 01329 break; 01330 01331 c--; 01332 if( vertical.Block_ScanBackward() ) 01333 { 01334 updated = 1; 01335 01336 do 01337 c--; 01338 while( c > 0 && vertical.Block_ScanBackward() ); 01339 01340 if( last < 2 || last > 5 ) 01341 d = 0; 01342 else if( ++d >= dm ) 01343 break; 01344 01345 last = 4; 01346 } 01347 } 01348 01349 if( c > 0 ) 01350 { 01351 if( last == 5 ) 01352 break; 01353 01354 c--; 01355 if( vertical.Block_ScanForward() ) 01356 { 01357 updated = 1; 01358 01359 do 01360 c--; 01361 while( c > 0 && vertical.Block_ScanForward() ); 01362 01363 if( last < 2 || last > 5 ) 01364 d = 0; 01365 else if( ++d >= dm ) 01366 break; 01367 01368 last = 5; 01369 } 01370 } 01371 01372 if( c > 0 ) 01373 { 01374 if( last == 6 ) 01375 break; 01376 01377 c--; 01378 if( horizontal.Block_SwitchWrongs() ) 01379 { 01380 updated = 1; 01381 last = 6; 01382 } 01383 } 01384 01385 if( c > 0 ) 01386 { 01387 if( last == 7 ) 01388 break; 01389 01390 c--; 01391 if( vertical.Block_SwitchWrongs() ) 01392 { 01393 updated = 1; 01394 last = 7; 01395 } 01396 } 01397 01398 if( last == 0 ) 01399 break; 01400 } 01401 01402 if( c <= 0 ) 01403 { 01404 // MessageBeep(MB_ICONEXCLAMATION); 01405 updated = -1; 01406 } 01407 01408 // Check customized connection if there's any clip against boxes 01409 { 01410 std::vector<CAutoRouterPath*>::iterator pathiter; 01411 pathiter = paths.begin(); 01412 01413 HRESULT hr = S_OK; 01414 while (pathiter != paths.end()) 01415 { 01416 CAutoRouterPath* path = *pathiter; 01417 01418 if (path->IsAutoRouted()) { // comment this if you want the check to run for fully customizable connections 01419 if (path->AreTherePathCustomizations()) 01420 { 01421 const CRect startBoxRect = path->GetStartBox(); 01422 const CRect endBoxRect = path->GetEndBox(); 01423 01424 std::vector<CAutoRouterBox*>::const_iterator boxiter = boxes.begin(); 01425 01426 while (boxiter != boxes.end()) 01427 { 01428 const CRect boxRect = (*boxiter)->GetRect(); 01429 bool isStartOrEndRect = (!startBoxRect.IsRectEmpty() && IsRectIn(startBoxRect, boxRect) || 01430 !endBoxRect.IsRectEmpty() && IsRectIn(endBoxRect, boxRect)); 01431 if (path->IsPathClip(boxRect, isStartOrEndRect)) 01432 { 01433 path->MarkPathCustomizationsForDeletion(aspect); 01434 updated = -2; 01435 } 01436 01437 ++boxiter; 01438 } 01439 } 01440 } 01441 01442 ++pathiter; 01443 } 01444 } 01445 01446 return updated; 01447 } 01448 01449 void CAutoRouterGraph::DeletePath(CAutoRouterPath* path) 01450 { 01451 ASSERT(path != NULL); 01452 if (path == NULL) 01453 return; 01454 01455 if( path->HasOwner() ) 01456 { 01457 ASSERT( path->GetOwner() == this ); 01458 01459 Remove(path); 01460 } 01461 01462 path->Destroy(); 01463 delete path; 01464 } 01465 01466 void CAutoRouterGraph::DeleteAll(bool addBackSelfEdges) 01467 { 01468 DeleteAllPaths(); 01469 DeleteAllBoxes(); 01470 DeleteAllEdges(); 01471 if (addBackSelfEdges) 01472 AddSelfEdges(); 01473 } 01474 01475 CAutoRouterPath* CAutoRouterGraph::GetPathAt(const CPoint& point, long nearness) 01476 { 01477 std::vector<CAutoRouterPath*>::iterator iter; 01478 iter = paths.begin(); 01479 01480 while (iter != paths.end()) 01481 { 01482 CAutoRouterPath* path = *iter; 01483 01484 if( path->IsPathAt(point, nearness) ) 01485 return path; 01486 01487 ++iter; 01488 } 01489 01490 return NULL; 01491 } 01492 01493 CAutoRouterPath* CAutoRouterGraph::AddPath(bool isAutoRouted, CAutoRouterPort* startport, CAutoRouterPort* endport) 01494 { 01495 CAutoRouterPath* path = new CAutoRouterPath(); 01496 01497 path->SetAutoRouting(isAutoRouted); 01498 path->SetStartPort(startport); 01499 path->SetEndPort(endport); 01500 Add(path); 01501 01502 return path; 01503 } 01504 01505 bool CAutoRouterGraph::IsEdgeFixed(CAutoRouterPath* path, const CPoint& startpoint, const CPoint& endpoint) 01506 { 01507 RoutingDirection d = GetDir(endpoint - startpoint); 01508 bool h = IsHorizontal(d); 01509 01510 CAutoRouterEdgeList& elist = GetEdgeList(h); 01511 01512 CAutoRouterEdge* edge = elist.GetEdge(path, startpoint, endpoint); 01513 if (edge != NULL) 01514 return edge->GetEdgeFixed() && !edge->GetEdgeCustomFixed(); 01515 01516 ASSERT(false); 01517 return true; 01518 } 01519 01520 CPoint* CAutoRouterGraph::GetSelfPoints(void) const 01521 { 01522 return (CPoint*)selfpoints; 01523 } 01524 01525 void CAutoRouterGraph::Destroy(void) 01526 { 01527 DeleteAll(false); 01528 01529 horizontal.SetOwner(NULL); 01530 vertical.SetOwner(NULL); 01531 } 01532 01533 #ifdef _DEBUG 01534 void CAutoRouterGraph::AssertValid() const 01535 { 01536 std::vector<CAutoRouterBox*>::const_iterator iter = boxes.begin(); 01537 01538 while (iter != boxes.end()) 01539 { 01540 AssertValidBox(*iter); 01541 ++iter; 01542 } 01543 01544 std::vector<CAutoRouterPath*>::const_iterator iter2 = paths.begin(); 01545 01546 while(iter2 != paths.end()) 01547 { 01548 AssertValidPath(*iter2); 01549 ++iter2; 01550 } 01551 } 01552 01553 void CAutoRouterGraph::AssertValidBox(CAutoRouterBox* box) const 01554 { 01555 box->AssertValid(); 01556 ASSERT( box->GetOwner() == this ); 01557 01558 std::vector<CAutoRouterBox*>::const_iterator iter = std::find(boxes.begin(), boxes.end(), box); 01559 ASSERT (iter != boxes.end()); 01560 } 01561 01562 void CAutoRouterGraph::AssertValidPath(CAutoRouterPath* path) const 01563 { 01564 path->AssertValid(); 01565 ASSERT( path->GetOwner() == this ); 01566 01567 std::vector<CAutoRouterPath*>::const_iterator iter = std::find(paths.begin(), paths.end(), path); 01568 ASSERT (iter != paths.end()); 01569 01570 CPointListPath& pointList = path->GetPointList(); 01571 01572 CAutoRouterPort* startPort = path->GetStartPort(); 01573 ASSERT(startPort != NULL); 01574 startPort->AssertValid(); 01575 CAutoRouterBox* ownerBox = startPort->GetOwner(); 01576 CAutoRouterGraph* boxOwnerGraph = ownerBox->GetOwner(); 01577 ASSERT( boxOwnerGraph == this ); 01578 ownerBox->AssertValidPort(startPort); 01579 01580 if( path->IsConnected() ) 01581 startPort->AssertValidStartEndPoint(pointList.GetHead(), Dir_None, 1); 01582 01583 CAutoRouterPort* endPort = path->GetEndPort(); 01584 ASSERT(endPort != NULL); 01585 endPort->AssertValid(); 01586 CAutoRouterBox* ownerBox2 = endPort->GetOwner(); 01587 ASSERT( ownerBox2->GetOwner() == this ); 01588 ownerBox2->AssertValidPort(endPort); 01589 01590 if( path->IsConnected() ) 01591 { 01592 endPort->AssertValidStartEndPoint(pointList.GetTail(), Dir_None, 0); 01593 } 01594 else 01595 { 01596 ASSERT( path->HasNoPoint() ); 01597 } 01598 01599 path->AssertValidPoints(); 01600 01601 if( !pointList.IsEmpty() ) 01602 { 01603 ASSERT( pointList.GetCount() >= 2 ); 01604 POSITION pos = pointList.GetHeadPosition(); 01605 ASSERT( pos != NULL ); 01606 01607 ASSERT( IsPointInBox(pointList.GetNext(pos)) ); 01608 01609 while( pos != NULL ) 01610 { 01611 CPoint p = pointList.GetNext(pos); 01612 if( pos != NULL ) 01613 ASSERT( !IsPointInBox(p) ); 01614 else 01615 ASSERT( IsPointInBox(p) ); 01616 } 01617 } 01618 } 01619 01620 void CAutoRouterGraph::DumpPaths(int pos, int c) 01621 { 01622 TRACE2("Paths dump pos %ld, c %ld:\n", pos, c); 01623 std::vector<CAutoRouterPath*>::iterator iter; 01624 iter = paths.begin(); 01625 int i = 0; 01626 01627 while (iter != paths.end()) 01628 { 01629 TRACE1("%ld. Path:\n", i); 01630 (*iter)->GetPointList().DumpPoints("DumpPaths"); 01631 01632 ++iter; 01633 i++; 01634 } 01635 01636 DumpEdgeLists(); 01637 } 01638 01639 void CAutoRouterGraph::DumpEdgeLists(void) 01640 { 01641 #ifdef _DEBUG_DEEP 01642 horizontal.DumpEdges("Horizontal edges:"); 01643 vertical.DumpEdges("Vertical edges:"); 01644 #endif 01645 } 01646 #endif 01647 01648 // CAutoRouterGraph