1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
5  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 /**
26  * @file object_2d.h
27  */
28 
29 #ifndef _OBJECT_2D_H_
30 #define _OBJECT_2D_H_
31 
32 #include "bbox_2d.h"
33 
34 class BOARD_ITEM;
35 
36 enum class INTERSECTION_RESULT
37 {
38     MISSES,
39     INTERSECTS,
40     FULL_INSIDE
41 };
42 
43 
44 enum class OBJECT_2D_TYPE
45 {
46     FILLED_CIRCLE,
47     CSG,
48     POLYGON,
49     DUMMYBLOCK,
50     POLYGON4PT,
51     RING,
52     ROUNDSEG,
53     TRIANGLE,
54     CONTAINER,
55     BVHCONTAINER,
56     MAX
57 };
58 
59 
60 class OBJECT_2D
61 {
62 public:
63     OBJECT_2D( OBJECT_2D_TYPE aObjType, const BOARD_ITEM& aBoardItem );
~OBJECT_2D()64     virtual ~OBJECT_2D() {}
65 
GetBoardItem()66     const BOARD_ITEM& GetBoardItem() const { return m_boardItem; }
67 
68     /**
69      * Test if the box overlaps the object.
70      *
71      * Conformance
72      * Implements the Overlaps function from the OGC Simple Feature Specification at
73      * http://www.opengeospatial.org/standards/sfa.
74      * a.Overlaps(b) ⇔ ( dim(I(a)) = dim(I(b)) = dim(I(a) ∩ I(b))) ∧ (a ∩ b ≠ a) ∧ (a ∩ b ≠ b)
75      * It means that the result dimension of an overlap is the same dimensions
76      * of the bounding box (so the overlap cannot be a point or a line) and one
77      * of the boxes cannot full contain the other box.
78      *
79      * @param aBBox is the bounding box to test.
80      * @return true if the BBox intersects the object or is inside it.
81      */
82     virtual bool Overlaps( const BBOX_2D& aBBox ) const = 0;
83 
84     /**
85      * a.Intersects(b) ⇔ !a.Disjoint(b) ⇔ !(a ∩ b = ∅)
86      */
87     virtual bool Intersects( const BBOX_2D& aBBox ) const = 0;
88 
89     /**
90      * @param aOutT a value between 0.0 and 1.0 in relation to the time of the hit of the segment.
91      */
92     virtual bool Intersect( const RAYSEG2D& aSegRay, float* aOutT, SFVEC2F* aNormalOut ) const = 0;
93 
94     /**
95      * Test this object if it's completely outside, intersects, or is completely inside \a aBBox.
96      *
97      * @return INTERSECTION_RESULT
98      */
99     virtual INTERSECTION_RESULT IsBBoxInside( const BBOX_2D& aBBox ) const = 0;
100 
101     virtual bool IsPointInside( const SFVEC2F& aPoint ) const = 0;
102 
GetBBox()103     const BBOX_2D& GetBBox() const { return m_bbox; }
104 
GetCentroid()105     const SFVEC2F& GetCentroid() const { return m_centroid; }
106 
GetObjectType()107     OBJECT_2D_TYPE GetObjectType() const { return m_obj_type; }
108 
109 protected:
110     BBOX_2D          m_bbox;
111     SFVEC2F          m_centroid;
112     OBJECT_2D_TYPE   m_obj_type;
113 
114     const BOARD_ITEM& m_boardItem;
115 };
116 
117 
118 
119 class OBJECT_2D_STATS
120 {
121 public:
ResetStats()122     void ResetStats()
123     {
124         memset( m_counter, 0, sizeof( unsigned int ) * static_cast<int>( OBJECT_2D_TYPE::MAX ) );
125     }
126 
GetCountOf(OBJECT_2D_TYPE aObjType)127     unsigned int GetCountOf( OBJECT_2D_TYPE aObjType ) const
128     {
129         return m_counter[static_cast<int>( aObjType )];
130     }
131 
AddOne(OBJECT_2D_TYPE aObjType)132     void AddOne( OBJECT_2D_TYPE aObjType )
133     {
134         m_counter[static_cast<int>( aObjType )]++;
135     }
136 
Instance()137     static OBJECT_2D_STATS& Instance()
138     {
139         if( !s_instance )
140             s_instance = new OBJECT_2D_STATS;
141 
142         return *s_instance;
143     }
144 
145 private:
OBJECT_2D_STATS()146     OBJECT_2D_STATS(){ ResetStats(); }
147     OBJECT_2D_STATS( const OBJECT_2D_STATS& old );
148     const OBJECT_2D_STATS& operator=( const OBJECT_2D_STATS& old );
~OBJECT_2D_STATS()149     ~OBJECT_2D_STATS(){}
150 
151     unsigned int m_counter[static_cast<int>( OBJECT_2D_TYPE::MAX )];
152 
153     static OBJECT_2D_STATS* s_instance;
154 };
155 
156 #endif // _OBJECT_2D_H_
157