1 /* Authors: Lutong Wang and Bangqi Xu */
2 /*
3  * Copyright (c) 2019, The Regents of the University of California
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *     * Redistributions of source code must retain the above copyright
9  *       notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above copyright
11  *       notice, this list of conditions and the following disclaimer in the
12  *       documentation and/or other materials provided with the distribution.
13  *     * Neither the name of the University nor the
14  *       names of its contributors may be used to endorse or promote products
15  *       derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE FOR ANY DIRECT,
21  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef _FR_SHAPE_H_
30 #define _FR_SHAPE_H_
31 
32 #include "db/infra/frSegStyle.h"
33 #include "db/obj/frFig.h"
34 
35 namespace fr {
36 class frNet;
37 class frPin;
38 class drPathSeg;
39 class taPathSeg;
40 class drPatchWire;
41 class frShape : public frPinFig
42 {
43  public:
44   // setters
45   virtual void setLayerNum(frLayerNum tmpLayerNum) = 0;
46   // getters
47   virtual frLayerNum getLayerNum() const = 0;
48   // others
49 
50   /* from frPinFig
51    * hasPin
52    * getPin
53    * addToPin
54    * removeFromPin
55    */
56 
57   /* from frConnFig
58    * hasNet
59    * getNet
60    * addToNet
61    * removeFromNet
62    */
63 
64   /* from frFig
65    * getBBox
66    * move
67    * overlaps
68    */
69 
70   virtual void setIter(frListIter<std::unique_ptr<frShape>>& in) = 0;
71   virtual frListIter<std::unique_ptr<frShape>> getIter() const = 0;
72 
73  protected:
74   // constructors
frShape()75   frShape() : frPinFig() {}
76 };
77 
78 class frRect : public frShape
79 {
80  public:
81   // constructors
frRect()82   frRect() : frShape(), box_(), layer_(0), owner_(nullptr) {}
frRect(const frRect & in)83   frRect(const frRect& in)
84       : frShape(in), box_(in.box_), layer_(in.layer_), owner_(in.owner_)
85   {
86   }
87   // setters
setBBox(const frBox & boxIn)88   void setBBox(const frBox& boxIn) { box_.set(boxIn); }
89   // getters
90   // others
isHor()91   bool isHor() const
92   {
93     frCoord xSpan = box_.right() - box_.left();
94     frCoord ySpan = box_.top() - box_.bottom();
95     return (xSpan >= ySpan) ? true : false;
96   }
width()97   frCoord width() const
98   {
99     frCoord xSpan = box_.right() - box_.left();
100     frCoord ySpan = box_.top() - box_.bottom();
101     return (xSpan > ySpan) ? ySpan : xSpan;
102   }
length()103   frCoord length() const
104   {
105     frCoord xSpan = box_.right() - box_.left();
106     frCoord ySpan = box_.top() - box_.bottom();
107     return (xSpan < ySpan) ? ySpan : xSpan;
108   }
typeId()109   frBlockObjectEnum typeId() const override { return frcRect; }
110 
111   /* from frShape
112    * setLayerNum
113    * getLayerNum
114    */
setLayerNum(frLayerNum numIn)115   void setLayerNum(frLayerNum numIn) override { layer_ = numIn; }
getLayerNum()116   frLayerNum getLayerNum() const override { return layer_; }
117 
118   /* from frPinFig
119    * hasPin
120    * getPin
121    * addToPin
122    * removeFromPin
123    */
hasPin()124   bool hasPin() const override
125   {
126     return (owner_) && (owner_->typeId() == frcPin);
127   }
128 
getPin()129   frPin* getPin() const override { return reinterpret_cast<frPin*>(owner_); }
130 
addToPin(frPin * in)131   void addToPin(frPin* in) override
132   {
133     owner_ = reinterpret_cast<frBlockObject*>(in);
134   }
135 
removeFromPin()136   void removeFromPin() override { owner_ = nullptr; }
137 
138   /* from frConnFig
139    * hasNet
140    * getNet
141    * addToNet
142    * removeFromNet
143    */
hasNet()144   bool hasNet() const override
145   {
146     return (owner_) && (owner_->typeId() == frcNet);
147   }
148 
getNet()149   frNet* getNet() const override { return reinterpret_cast<frNet*>(owner_); }
150 
addToNet(frNet * in)151   void addToNet(frNet* in) override
152   {
153     owner_ = reinterpret_cast<frBlockObject*>(in);
154   }
155 
removeFromNet()156   void removeFromNet() override { owner_ = nullptr; }
157 
158   /* from frFig
159    * getBBox
160    * move, in .cpp
161    * overlaps in .cpp
162    */
getBBox(frBox & boxIn)163   void getBBox(frBox& boxIn) const override { boxIn.set(box_); }
move(const frTransform & xform)164   void move(const frTransform& xform) override { box_.transform(xform); }
overlaps(const frBox & box)165   bool overlaps(const frBox& box) const override
166   {
167     frBox rectBox;
168     getBBox(rectBox);
169     return rectBox.overlaps(box);
170   }
171 
setIter(frListIter<std::unique_ptr<frShape>> & in)172   void setIter(frListIter<std::unique_ptr<frShape>>& in) override
173   {
174     iter_ = in;
175   }
getIter()176   frListIter<std::unique_ptr<frShape>> getIter() const override
177   {
178     return iter_;
179   }
180 
181  protected:
182   frBox box_;
183   frLayerNum layer_;
184   frBlockObject* owner_;  // general back pointer 0
185   frListIter<std::unique_ptr<frShape>> iter_;
186 };
187 
188 class frPatchWire : public frShape
189 {
190  public:
191   // constructors
frPatchWire()192   frPatchWire() : frShape(), offsetBox_(), origin_(), layer_(0), owner_(nullptr)
193   {
194   }
frPatchWire(const frPatchWire & in)195   frPatchWire(const frPatchWire& in)
196       : frShape(),
197         offsetBox_(in.offsetBox_),
198         origin_(in.origin_),
199         layer_(in.layer_),
200         owner_(in.owner_)
201   {
202   }
203   frPatchWire(const drPatchWire& in);
204   // setters
setOffsetBox(const frBox & in)205   void setOffsetBox(const frBox& in) { offsetBox_.set(in); }
setOrigin(const frPoint & in)206   void setOrigin(const frPoint& in) { origin_.set(in); }
207   // getters
208   // others
typeId()209   frBlockObjectEnum typeId() const override { return frcPatchWire; }
210 
211   /* from frShape
212    * setLayerNum
213    * getLayerNum
214    */
setLayerNum(frLayerNum numIn)215   void setLayerNum(frLayerNum numIn) override { layer_ = numIn; }
getLayerNum()216   frLayerNum getLayerNum() const override { return layer_; }
217 
218   /* from frPinFig
219    * hasPin
220    * getPin
221    * addToPin
222    * removeFromPin
223    */
hasPin()224   bool hasPin() const override
225   {
226     return (owner_) && (owner_->typeId() == frcPin);
227   }
228 
getPin()229   frPin* getPin() const override { return reinterpret_cast<frPin*>(owner_); }
230 
addToPin(frPin * in)231   void addToPin(frPin* in) override
232   {
233     owner_ = reinterpret_cast<frBlockObject*>(in);
234   }
235 
removeFromPin()236   void removeFromPin() override { owner_ = nullptr; }
237 
238   /* from frConnFig
239    * hasNet
240    * getNet
241    * addToNet
242    * removeFromNet
243    */
hasNet()244   bool hasNet() const override
245   {
246     return (owner_) && (owner_->typeId() == frcNet);
247   }
248 
getNet()249   frNet* getNet() const override { return reinterpret_cast<frNet*>(owner_); }
250 
addToNet(frNet * in)251   void addToNet(frNet* in) override
252   {
253     owner_ = reinterpret_cast<frBlockObject*>(in);
254   }
255 
removeFromNet()256   void removeFromNet() override { owner_ = nullptr; }
257 
258   /* from frFig
259    * getBBox
260    * move, in .cpp
261    * overlaps in .cpp
262    */
getBBox(frBox & boxIn)263   void getBBox(frBox& boxIn) const override
264   {
265     frTransform xform(origin_);
266     boxIn.set(offsetBox_);
267     boxIn.transform(xform);
268   }
getOffsetBox(frBox & boxIn)269   void getOffsetBox(frBox& boxIn) const { boxIn.set(offsetBox_); }
getOrigin(frPoint & in)270   void getOrigin(frPoint& in) const { in.set(origin_); }
move(const frTransform & xform)271   void move(const frTransform& xform) override {}
overlaps(const frBox & box)272   bool overlaps(const frBox& box) const override
273   {
274     frBox rectBox;
275     getBBox(rectBox);
276     return rectBox.overlaps(box);
277   }
278 
setIter(frListIter<std::unique_ptr<frShape>> & in)279   void setIter(frListIter<std::unique_ptr<frShape>>& in) override
280   {
281     iter_ = in;
282   }
getIter()283   frListIter<std::unique_ptr<frShape>> getIter() const override
284   {
285     return iter_;
286   }
287 
288  protected:
289   // frBox          box_;
290   frBox offsetBox_;
291   frPoint origin_;
292   frLayerNum layer_;
293   frBlockObject* owner_;  // general back pointer 0
294   frListIter<std::unique_ptr<frShape>> iter_;
295 };
296 
297 class frPolygon : public frShape
298 {
299  public:
300   // constructors
frPolygon()301   frPolygon() : frShape(), points_(), layer_(0), owner_(nullptr) {}
frPolygon(const frPolygon & in)302   frPolygon(const frPolygon& in)
303       : frShape(), points_(in.points_), layer_(in.layer_), owner_(in.owner_)
304   {
305   }
306   // setters
setPoints(const std::vector<frPoint> & pointsIn)307   void setPoints(const std::vector<frPoint>& pointsIn) { points_ = pointsIn; }
308   // getters
getPoints()309   const std::vector<frPoint>& getPoints() const { return points_; }
310   // others
typeId()311   frBlockObjectEnum typeId() const override { return frcPolygon; }
312 
313   /* from frShape
314    * setLayerNum
315    * getLayerNum
316    */
setLayerNum(frLayerNum numIn)317   void setLayerNum(frLayerNum numIn) override { layer_ = numIn; }
getLayerNum()318   frLayerNum getLayerNum() const override { return layer_; }
319 
320   /* from frPinFig
321    * hasPin
322    * getPin
323    * addToPin
324    * removeFromPin
325    */
hasPin()326   bool hasPin() const override
327   {
328     return (owner_) && (owner_->typeId() == frcPin);
329   }
330 
getPin()331   frPin* getPin() const override { return reinterpret_cast<frPin*>(owner_); }
332 
addToPin(frPin * in)333   void addToPin(frPin* in) override
334   {
335     owner_ = reinterpret_cast<frBlockObject*>(in);
336   }
337 
removeFromPin()338   void removeFromPin() override { owner_ = nullptr; }
339 
340   /* from frConnFig
341    * hasNet
342    * getNet
343    * addToNet
344    * removeFromNet
345    */
hasNet()346   bool hasNet() const override
347   {
348     return (owner_) && (owner_->typeId() == frcNet);
349   }
350 
getNet()351   frNet* getNet() const override { return reinterpret_cast<frNet*>(owner_); }
352 
addToNet(frNet * in)353   void addToNet(frNet* in) override
354   {
355     owner_ = reinterpret_cast<frBlockObject*>(in);
356   }
357 
removeFromNet()358   void removeFromNet() override { owner_ = nullptr; }
359 
360   /* from frFig
361    * getBBox
362    * move, in .cpp
363    * overlaps, in .cpp
364    */
getBBox(frBox & boxIn)365   void getBBox(frBox& boxIn) const override
366   {
367     frCoord llx = 0;
368     frCoord lly = 0;
369     frCoord urx = 0;
370     frCoord ury = 0;
371     if (points_.size()) {
372       llx = points_.begin()->x();
373       urx = points_.begin()->x();
374       lly = points_.begin()->y();
375       ury = points_.begin()->y();
376     }
377     for (auto& point : points_) {
378       llx = (llx < point.x()) ? llx : point.x();
379       lly = (lly < point.y()) ? lly : point.y();
380       urx = (urx > point.x()) ? urx : point.x();
381       ury = (ury > point.y()) ? ury : point.y();
382     }
383     boxIn.set(llx, lly, urx, ury);
384   }
move(const frTransform & xform)385   void move(const frTransform& xform) override
386   {
387     for (auto& point : points_) {
388       point.transform(xform);
389     }
390   }
overlaps(const frBox & box)391   bool overlaps(const frBox& box) const override { return false; }
392 
setIter(frListIter<std::unique_ptr<frShape>> & in)393   void setIter(frListIter<std::unique_ptr<frShape>>& in) override
394   {
395     iter_ = in;
396   }
getIter()397   frListIter<std::unique_ptr<frShape>> getIter() const override
398   {
399     return iter_;
400   }
401 
402  protected:
403   std::vector<frPoint> points_;
404   frLayerNum layer_;
405   frBlockObject* owner_;
406   frListIter<std::unique_ptr<frShape>> iter_;
407 };
408 
409 class frPathSeg : public frShape
410 {
411  public:
412   // constructors
frPathSeg()413   frPathSeg()
414       : frShape(),
415         begin_(),
416         end_(),
417         layer_(0),
418         style_(),
419         owner_(nullptr),
420         tapered_(false)
421   {
422   }
frPathSeg(const frPathSeg & in)423   frPathSeg(const frPathSeg& in)
424       : begin_(in.begin_),
425         end_(in.end_),
426         layer_(in.layer_),
427         style_(in.style_),
428         owner_(in.owner_),
429         tapered_(in.tapered_)
430   {
431   }
432   frPathSeg(const drPathSeg& in);
433   frPathSeg(const taPathSeg& in);
434   // getters
getPoints(frPoint & beginIn,frPoint & endIn)435   void getPoints(frPoint& beginIn, frPoint& endIn) const
436   {
437     beginIn.set(begin_);
438     endIn.set(end_);
439   }
getBeginPoint()440   const frPoint& getBeginPoint() const { return begin_; }
getEndPoint()441   const frPoint& getEndPoint() const { return end_; }
getStyle(frSegStyle & styleIn)442   void getStyle(frSegStyle& styleIn) const
443   {
444     styleIn.setBeginStyle(style_.getBeginStyle(), style_.getBeginExt());
445     styleIn.setEndStyle(style_.getEndStyle(), style_.getEndExt());
446     styleIn.setWidth(style_.getWidth());
447   }
getBeginStyle()448   frEndStyle getBeginStyle() const { return style_.getBeginStyle(); }
getEndStyle()449   frEndStyle getEndStyle() const { return style_.getEndStyle(); }
getEndExt()450   frUInt4 getEndExt() const { return style_.getEndExt(); }
getBeginExt()451   frUInt4 getBeginExt() const { return style_.getBeginExt(); }
isVertical()452   bool isVertical() const { return begin_.x() == end_.x(); }
high()453   frCoord high() const { return isVertical() ? end_.y() : end_.x(); }
low()454   frCoord low() const { return isVertical() ? begin_.y() : begin_.x(); }
455   // setters
setPoints(const frPoint & beginIn,const frPoint & endIn)456   void setPoints(const frPoint& beginIn, const frPoint& endIn)
457   {
458     begin_.set(beginIn);
459     end_.set(endIn);
460   }
setStyle(const frSegStyle & styleIn)461   void setStyle(const frSegStyle& styleIn)
462   {
463     style_.setBeginStyle(styleIn.getBeginStyle(), styleIn.getBeginExt());
464     style_.setEndStyle(styleIn.getEndStyle(), styleIn.getEndExt());
465     style_.setWidth(styleIn.getWidth());
466   }
467   void setBeginStyle(frEndStyle bs, frUInt4 ext = 0)
468   {
469     style_.setBeginStyle(bs, ext);
470   }
471   void setEndStyle(frEndStyle es, frUInt4 ext = 0)
472   {
473     style_.setEndStyle(es, ext);
474   }
475   // others
typeId()476   frBlockObjectEnum typeId() const override { return frcPathSeg; }
477 
478   /* from frShape
479    * setLayerNum
480    * getLayerNum
481    */
setLayerNum(frLayerNum numIn)482   void setLayerNum(frLayerNum numIn) override { layer_ = numIn; }
getLayerNum()483   frLayerNum getLayerNum() const override { return layer_; }
484 
485   /* from frPinFig
486    * hasPin
487    * getPin
488    * addToPin
489    * removeFromPin
490    */
hasPin()491   bool hasPin() const override
492   {
493     return (owner_) && (owner_->typeId() == frcPin);
494   }
495 
getPin()496   frPin* getPin() const override { return reinterpret_cast<frPin*>(owner_); }
497 
addToPin(frPin * in)498   void addToPin(frPin* in) override
499   {
500     owner_ = reinterpret_cast<frBlockObject*>(in);
501   }
502 
removeFromPin()503   void removeFromPin() override { owner_ = nullptr; }
504 
505   /* from frConnFig
506    * hasNet
507    * getNet
508    * addToNet
509    * removeFromNet
510    */
hasNet()511   bool hasNet() const override
512   {
513     return (owner_) && (owner_->typeId() == frcNet);
514   }
515 
getNet()516   frNet* getNet() const override { return reinterpret_cast<frNet*>(owner_); }
517 
addToNet(frNet * in)518   void addToNet(frNet* in) override
519   {
520     owner_ = reinterpret_cast<frBlockObject*>(in);
521   }
522 
removeFromNet()523   void removeFromNet() override { owner_ = nullptr; }
524 
525   /* from frFig
526    * getBBox
527    * move, in .cpp
528    * overlaps, in .cpp
529    */
530   // needs to be updated
getBBox(frBox & boxIn)531   void getBBox(frBox& boxIn) const override
532   {
533     bool isHorizontal = true;
534     if (begin_.x() == end_.x()) {
535       isHorizontal = false;
536     }
537     auto width = style_.getWidth();
538     auto beginExt = style_.getBeginExt();
539     auto endExt = style_.getEndExt();
540     if (isHorizontal) {
541       boxIn.set(begin_.x() - beginExt,
542                 begin_.y() - width / 2,
543                 end_.x() + endExt,
544                 end_.y() + width / 2);
545     } else {
546       boxIn.set(begin_.x() - width / 2,
547                 begin_.y() - beginExt,
548                 end_.x() + width / 2,
549                 end_.y() + endExt);
550     }
551   }
move(const frTransform & xform)552   void move(const frTransform& xform) override
553   {
554     begin_.transform(xform);
555     end_.transform(xform);
556   }
overlaps(const frBox & box)557   bool overlaps(const frBox& box) const override { return false; }
558 
setIter(frListIter<std::unique_ptr<frShape>> & in)559   void setIter(frListIter<std::unique_ptr<frShape>>& in) override
560   {
561     iter_ = in;
562   }
getIter()563   frListIter<std::unique_ptr<frShape>> getIter() const override
564   {
565     return iter_;
566   }
setTapered(bool t)567   void setTapered(bool t) { tapered_ = t; }
isTapered()568   bool isTapered() const { return tapered_; }
569 
intersectsCenterLine(const frPoint & pt)570   bool intersectsCenterLine(const frPoint& pt) {
571       return pt.x() >= begin_.x() && pt.x() <= end_.x() && pt.y() >= begin_.y()
572               && pt.y() <= end_.y();
573   }
574  protected:
575   frPoint begin_;  // begin always smaller than end, assumed
576   frPoint end_;
577   frLayerNum layer_;
578   frSegStyle style_;
579   frBlockObject* owner_;
580   bool tapered_;
581   frListIter<std::unique_ptr<frShape>> iter_;
582 };
583 }  // namespace fr
584 
585 #endif
586