KiCad PCB EDA Suite
citemlayercsg2d.cpp
Go to the documentation of this file.
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-2016 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 
30 #include "citemlayercsg2d.h"
31 #include "3d_fastmath.h"
32 #include <wx/debug.h>
33 
35  std::vector<const COBJECT2D*>* aObjectB, const COBJECT2D* aObjectC,
36  const BOARD_ITEM& aBoardItem )
37  : COBJECT2D( OBJECT2D_TYPE::CSG, aBoardItem ),
38  m_objectA( aObjectA ),
39  m_objectB( aObjectB ),
40  m_objectC( aObjectC )
41 {
42  wxASSERT( aObjectA );
43 
44  m_bbox.Reset();
45  m_bbox.Set( aObjectA->GetBBox() );
48 
49  wxASSERT( m_bbox.IsInitialized() );
50 }
51 
52 
54 {
55  if( ((void*)m_objectB != CSGITEM_EMPTY) &&
56  ((void*)m_objectB != CSGITEM_FULL) )
57  {
58  delete m_objectB;
59  m_objectB = NULL;
60  }
61 }
62 
63 
64 bool CITEMLAYERCSG2D::Intersects( const CBBOX2D &aBBox ) const
65 {
66  return m_bbox.Intersects( aBBox );
67  // !TODO: improove this implementation
68  //return false;
69 }
70 
71 
72 bool CITEMLAYERCSG2D::Overlaps( const CBBOX2D &aBBox ) const
73 {
74  // NOT IMPLEMENTED
75  return false;
76 }
77 
78 // Based on ideas and implementation by Nick Chapman
79 // http://homepages.paradise.net.nz/nickamy/raytracer/raytracer.htm
80 bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
81  float *aOutT,
82  SFVEC2F *aNormalOut ) const
83 {
84  wxASSERT( aOutT );
85  wxASSERT( aNormalOut );
86 
88  return false;
89 
90  float currentRayDist;
91  SFVEC2F currentRayPos;
92  SFVEC2F currentNormal;
93 
94  if( m_objectA->IsPointInside( aSegRay.m_Start ) )
95  {
96  // start ray point off where it is now (at the origin)
97  currentRayDist = 0.0f;
98  currentRayPos = aSegRay.m_Start;
99  }
100  else
101  {
102  //move ray point to start of main object
103  if( !m_objectA->Intersect( aSegRay, &currentRayDist, &currentNormal ) )
104  return false;
105 
106  currentRayPos = aSegRay.atNormalized( NextFloatDown( currentRayDist ) );
107  }
108 
109  //wxASSERT( (currentRayDist >= 0.0f) && (currentRayDist <= 1.0f) );
110 
111 
112  // move through the union of subtracted regions
113  bool hitSubRegion = false;
114 
115  if( m_objectB )
116  {
117  while(1)
118  {
119  bool wasInsideSubVol = false;
120 
121  //check against all subbed objects
122  for( unsigned int i = 0; i < m_objectB->size(); ++i )
123  {
124  if( ((const COBJECT2D *)(*m_objectB)[i])->IsPointInside( currentRayPos ) )
125  {
126  hitSubRegion = true;
127 
128  // ray point is inside a subtracted region, so move it to the end of the
129  // subtracted region
130  float hitDist;
131  if( !((const COBJECT2D *)(*m_objectB)[i])->Intersect( aSegRay,
132  &hitDist,
133  &currentNormal ) )
134  return false; // ray hit main object but did not leave subtracted volume
135 
136  wxASSERT( hitDist <= 1.0f );
137 
138  if( hitDist > currentRayDist )
139  currentRayDist = hitDist;
140 
141  currentRayDist += 0.0001f;
142 
143  // ray has left this specific subtracted object volume
144  currentRayPos = aSegRay.atNormalized( currentRayDist );
145 
146  if( m_objectA->IsPointInside( currentRayPos ) )
147  {
148  wasInsideSubVol = true;
149 
150  break;
151  }
152  }
153  }
154 
155  if( !wasInsideSubVol )
156  break; // ray has succesfully passed through all subtracted regions
157 
158  if( currentRayDist >= 1.0f )
159  break;
160  }
161  }
162 
163  //ray is not inside any of the specific subtracted regions
164 
165  if( hitSubRegion )
166  {
167  //if( !m_objectA->IsPointInside( currentRayPos ) )
168  // return false; // ray got right through the hole in the object!
169 
170  currentNormal *= -1.0f;
171  }
172  else
173  {
174  //ray just hit the main object without hitting any holes
175  }
176 
177  *aNormalOut = currentNormal;
178  *aOutT = currentRayDist;
179 
180  return true;
181 }
182 
183 
185 {
186 
187  // !TODO:
188 
190 }
191 
192 
193 bool CITEMLAYERCSG2D::IsPointInside( const SFVEC2F &aPoint ) const
194 {
195  // Perform the operation (A - B) /\ C
196 
197  if( m_objectA->IsPointInside( aPoint ) )
198  {
199 
200  if( m_objectB != CSGITEM_EMPTY)
201  for( unsigned int i = 0; i< m_objectB->size(); i++ )
202  {
203  if( (*m_objectB)[i]->IsPointInside( aPoint ) )
204  return false;
205  }
206 
207  // !TODO: not yet implemented
208  //if( m_objectC && m_objectC != CSGITEM_FULL )
209  // return m_objectC->IsPointInside( aPoint );
210 
211  return true;
212  }
213 
214  return false;
215 }
INTERSECTION_RESULT
Definition: cobject2d.h:38
SFVEC2F atNormalized(float t) const
Function atNormalized - returns the position at t t - value 0.0 ...
Definition: ray.h:139
Defines math related functions.
OBJECT2D_TYPE GetObjectType() const
Definition: cobject2d.h:125
std::vector< const COBJECT2D * > * m_objectB
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
const COBJECT2D * m_objectA
CBBOX manages a bounding box defined by two SFVEC2F min max points.
Definition: cbbox2d.h:40
virtual bool Intersect(const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut) const =0
Function Intersect.
bool Intersects(const CBBOX2D &aBBox) const override
Function Intersects.
#define CSGITEM_EMPTY
This class is used to make constructive solig geometry for items objects on layers.
void Reset()
Function Reset reset the bounding box to zero and de-initialized it.
Definition: cbbox2d.cpp:88
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
#define NULL
float NextFloatDown(float v)
Definition: 3d_fastmath.h:157
CITEMLAYERCSG2D(const COBJECT2D *aObjectA, std::vector< const COBJECT2D * > *aObjectB, const COBJECT2D *aObjectC, const BOARD_ITEM &aBoardItem)
bool Intersects(const CBBOX2D &aBBox) const
Function Intersects test if a bounding box intersects this box.
Definition: cbbox2d.cpp:213
void Set(const SFVEC2F &aPbMin, const SFVEC2F &aPbMax)
Function Set Set bounding box with new parameters.
Definition: cbbox2d.cpp:61
bool IsInitialized() const
Function IsInitialized check if this bounding box is already initialized.
Definition: cbbox2d.cpp:79
#define CSGITEM_FULL
bool Intersect(const RAYSEG2D &aSegRay, float *aOutT, SFVEC2F *aNormalOut) const override
Function Intersect.
void ScaleNextUp()
Function ScaleNextUp scales a bounding box to the next float representation making it larger.
Definition: cbbox2d.cpp:164
CBBOX2D m_bbox
Definition: cobject2d.h:65
bool IsPointInside(const SFVEC2F &aPoint) const override
SFVEC2F m_Start
Definition: ray.h:112
SFVEC2F m_centroid
Definition: cobject2d.h:66
OBJECT2D_TYPE
Definition: cobject2d.h:46
bool Overlaps(const CBBOX2D &aBBox) const override
Function Overlaps.
SFVEC2F GetCenter() const
Function GetCenter return the center point of the bounding box.
Definition: cbbox2d.cpp:121
virtual bool IsPointInside(const SFVEC2F &aPoint) const =0
const CBBOX2D & GetBBox() const
Definition: cobject2d.h:121
INTERSECTION_RESULT IsBBoxInside(const CBBOX2D &aBBox) const override
Function IsBBoxInside.
Definition: ray.h:110