KiCad PCB EDA Suite
opengl_utils.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 <[email protected]>
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 #include "../../common_ogl/openGL_includes.h"
26 #include "opengl_utils.h"
27 #include <trigo.h>
28 #include <wx/debug.h> // For the wxASSERT
29 
30 #define RADPERDEG 0.0174533
31 
32 void DrawRoundArrow( SFVEC3F aPosition, SFVEC3F aTargetPos, float aSize )
33 {
34  wxASSERT( aSize > 0.0f );
35 
36  SFVEC3F vec = aTargetPos - aPosition;
37  float length = glm::length( vec );
38 
39  GLUquadricObj *quadObj;
40 
41  glPushMatrix ();
42 
43  glTranslatef( aPosition.x, aPosition.y, aPosition.z );
44 
45  if( ( vec.x != 0.0f ) || ( vec.y != 0.0f ) )
46  {
47  glRotatef( atan2( vec.y, vec.x ) / RADPERDEG, 0.0f, 0.0f, 1.0f );
48  glRotatef( atan2( sqrt( vec.x * vec.x + vec.y * vec.y ), vec.z ) / RADPERDEG,
49  0.0f, 1.0f, 0.0f );
50 
51  }
52  else if( vec.z < 0.0f )
53  {
54  glRotatef( 180.0f, 1.0f, 0.0f, 0.0f );
55  }
56 
57  glTranslatef( 0.0f, 0.0f, length - 4.0f * aSize );
58 
59  quadObj = gluNewQuadric();
60  gluQuadricDrawStyle( quadObj, GLU_FILL );
61  gluQuadricNormals( quadObj, GLU_SMOOTH );
62  gluCylinder( quadObj, 2.0 * aSize, 0.0, 4.0 * aSize, 12, 1 );
63  gluDeleteQuadric( quadObj );
64 
65  quadObj = gluNewQuadric();
66  gluQuadricDrawStyle( quadObj, GLU_FILL );
67  gluQuadricNormals( quadObj, GLU_SMOOTH );
68  gluDisk( quadObj, 0.0, 2.0 * aSize, 12, 1 );
69  gluDeleteQuadric( quadObj );
70 
71  quadObj = gluNewQuadric();
72  gluQuadricDrawStyle( quadObj, GLU_FILL );
73  gluQuadricNormals( quadObj, GLU_SMOOTH );
74  gluDisk( quadObj, 0.0, aSize, 12, 1 );
75  gluDeleteQuadric( quadObj );
76 
77 
78  quadObj = gluNewQuadric();
79  gluQuadricDrawStyle( quadObj, GLU_FILL );
80  gluQuadricNormals( quadObj, GLU_SMOOTH );
81  gluSphere( quadObj, aSize, 24, 24 );
82  gluDeleteQuadric( quadObj );
83 
84  glTranslatef( 0.0f , 0.0f ,-length + 4.0f * aSize );
85 
86  quadObj = gluNewQuadric();
87  gluQuadricDrawStyle( quadObj, GLU_FILL );
88  gluQuadricNormals( quadObj, GLU_SMOOTH );
89  gluCylinder( quadObj, aSize, aSize, length - 4.0 * aSize, 12, 1 );
90  gluDeleteQuadric( quadObj );
91 
92  quadObj = gluNewQuadric();
93  gluQuadricDrawStyle( quadObj, GLU_FILL );
94  gluQuadricNormals( quadObj, GLU_SMOOTH );
95  gluDisk( quadObj, 0.0, aSize, 12, 1 );
96  gluDeleteQuadric( quadObj );
97 
98  glPopMatrix ();
99 }
100 
101 
102 void DrawBoundingBox( const BBOX_3D& aBBox )
103 {
104  wxASSERT( aBBox.IsInitialized() );
105 
106  glBegin( GL_LINE_LOOP );
107  glVertex3f( aBBox.Min().x, aBBox.Min().y, aBBox.Min().z );
108  glVertex3f( aBBox.Max().x, aBBox.Min().y, aBBox.Min().z );
109  glVertex3f( aBBox.Max().x, aBBox.Max().y, aBBox.Min().z );
110  glVertex3f( aBBox.Min().x, aBBox.Max().y, aBBox.Min().z );
111  glEnd();
112 
113  glBegin( GL_LINE_LOOP );
114  glVertex3f( aBBox.Min().x, aBBox.Min().y, aBBox.Max().z );
115  glVertex3f( aBBox.Max().x, aBBox.Min().y, aBBox.Max().z );
116  glVertex3f( aBBox.Max().x, aBBox.Max().y, aBBox.Max().z );
117  glVertex3f( aBBox.Min().x, aBBox.Max().y, aBBox.Max().z );
118  glEnd();
119 
120  glBegin( GL_LINE_STRIP );
121  glVertex3f( aBBox.Min().x, aBBox.Min().y, aBBox.Min().z );
122  glVertex3f( aBBox.Min().x, aBBox.Min().y, aBBox.Max().z );
123  glEnd();
124 
125  glBegin( GL_LINE_STRIP );
126  glVertex3f( aBBox.Max().x, aBBox.Min().y, aBBox.Min().z );
127  glVertex3f( aBBox.Max().x, aBBox.Min().y, aBBox.Max().z );
128  glEnd();
129 
130  glBegin( GL_LINE_STRIP );
131  glVertex3f( aBBox.Max().x, aBBox.Max().y, aBBox.Min().z );
132  glVertex3f( aBBox.Max().x, aBBox.Max().y, aBBox.Max().z );
133  glEnd();
134 
135  glBegin( GL_LINE_STRIP );
136  glVertex3f( aBBox.Min().x, aBBox.Max().y, aBBox.Min().z );
137  glVertex3f( aBBox.Min().x, aBBox.Max().y, aBBox.Max().z );
138  glEnd();
139 }
140 
141 
142 void DrawHalfOpenCylinder( unsigned int aNrSidesPerCircle )
143 {
144  if( aNrSidesPerCircle > 1 )
145  {
146  const float radius = 0.5f;
147  const int delta = 3600 / aNrSidesPerCircle;
148 
149  // Generate bottom
150  glNormal3f( 0.0f, 0.0f,-1.0f );
151  glBegin( GL_TRIANGLE_FAN );
152  glVertex3f( 0.0, 0.0, 0.0 ); // This is the V0 of the FAN
153 
154  for( int ii = 0; ii < 1800; ii += delta )
155  {
156  SFVEC2D corner = SFVEC2D( 0.0, radius );
157  RotatePoint( &corner.x, &corner.y, ii );
158  glVertex3f( corner.x, corner.y, 0.0 );
159  }
160 
161  glVertex3d( 0.0, -radius, 0.0 );
162  glEnd();
163 
164  // Generate top
165  glNormal3f( 0.0f, 0.0f, 1.0f );
166  glBegin( GL_TRIANGLE_FAN );
167  glVertex3f( 0.0, 0.0, 1.0 ); // This is the V0 of the FAN
168 
169  for( int ii = 1800; ii > 0; ii -= delta )
170  {
171  SFVEC2D corner = SFVEC2D( 0.0, radius );
172 
173  RotatePoint( &corner.x, &corner.y, ii );
174  glVertex3f( corner.x, corner.y, 1.0 );
175  }
176 
177  glVertex3f( 0.0, radius, 1.0 );
178  glEnd();
179 
180  // Generate contours
181  glBegin( GL_QUAD_STRIP );
182 
183  for( int ii = 1800; ii > 0; ii -= delta )
184  {
185  SFVEC2D corner = SFVEC2D( 0.0, radius );
186 
187  RotatePoint( &corner.x, &corner.y, ii );
188  glNormal3f( corner.x * 2.0f, corner.y * 2.0f, 0.0f );
189  glVertex3f( corner.x, corner.y, 1.0 );
190  glVertex3f( corner.x, corner.y, 0.0 );
191  }
192 
193  glNormal3f( 0.0, 1.0f, 0.0f );
194  glVertex3d( 0.0, radius, 1.0 );
195  glVertex3d( 0.0, radius, 0.0 );
196  glEnd();
197  }
198 }
199 
200 
201 void DrawSegment( const ROUND_SEGMENT_2D& aSegment, unsigned int aNrSidesPerCircle )
202 {
203  glPushMatrix();
204 
205  const SFVEC2F& start = aSegment.GetStart();
206  const SFVEC2F& end_minus_start = aSegment.GetEnd_minus_Start();
207  const float radius = aSegment.GetRadius();
208  const float width = aSegment.GetWidth();
209  const float length = aSegment.GetLength();
210 
211  glTranslatef( start.x, start.y, 0.0f );
212 
213  if( ( end_minus_start.x != 0.0f ) || ( end_minus_start.y != 0.0f ) )
214  {
215  glRotatef( atan2( end_minus_start.y, end_minus_start.x ) / RADPERDEG, 0.0f, 0.0f, 1.0f );
216  }
217 
218  glPushMatrix();
219  glTranslatef( length, 0.0, 0.0f );
220  glScalef( width, width, 1.0f );
221  DrawHalfOpenCylinder( aNrSidesPerCircle );
222  glPopMatrix();
223 
224  glBegin( GL_QUADS );
225  glNormal3f( 0.0,-1.0, 0.0 );
226  glVertex3f( length,-radius, 1.0 );
227  glVertex3f( 0.0, -radius, 1.0 );
228  glVertex3f( 0.0, -radius, 0.0 );
229  glVertex3f( length,-radius, 0.0 );
230  glEnd();
231 
232  glBegin( GL_QUADS );
233  glNormal3f( 0.0, 1.0, 0.0 );
234  glVertex3f( length, radius, 0.0 );
235  glVertex3f( 0.0, radius, 0.0 );
236  glVertex3f( 0.0, radius, 1.0 );
237  glVertex3f( length, radius, 1.0 );
238  glEnd();
239 
240  glBegin( GL_QUADS );
241  glNormal3f( 0.0, 0.0, 1.0 );
242  glVertex3f( length, radius, 1.0 );
243  glVertex3f( 0.0, radius, 1.0 );
244  glVertex3f( 0.0, -radius, 1.0 );
245  glVertex3f( length,-radius, 1.0 );
246  glEnd();
247 
248  glBegin( GL_QUADS );
249  glNormal3f( 0.0, 0.0,-1.0 );
250  glVertex3f( length,-radius, 0.0 );
251  glVertex3f( 0.0, -radius, 0.0 );
252  glVertex3f( 0.0, radius, 0.0 );
253  glVertex3f( length, radius, 0.0 );
254  glEnd();
255 
256  glScalef( width, width, 1.0f );
257  glRotatef( 180, 0.0, 0.0, 1.0 );
258  DrawHalfOpenCylinder( aNrSidesPerCircle );
259 
260  glPopMatrix ();
261 }
const SFVEC3F & Max() const
Return the maximum vertex pointer.
Definition: bbox_3d.h:198
void DrawBoundingBox(const BBOX_3D &aBBox)
Draw the bounding box lines.
float GetRadius() const
Manage a bounding box defined by two SFVEC3F min max points.
Definition: bbox_3d.h:41
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
void DrawHalfOpenCylinder(unsigned int aNrSidesPerCircle)
Draw a half open cylinder with diameter 1.0f and height 1.0f.
const SFVEC3F & Min() const
Return the minimum vertex pointer.
Definition: bbox_3d.h:191
void DrawSegment(const ROUND_SEGMENT_2D &aSegment, unsigned int aNrSidesPerCircle)
Draw a thick line segment with rounded ends.
glm::vec2 SFVEC2F
Definition: xv3d_types.h:42
float GetLength() const
bool IsInitialized() const
Check if this bounding box is already initialized.
Definition: bbox_3d.cpp:88
#define RADPERDEG
void DrawRoundArrow(SFVEC3F aPosition, SFVEC3F aTargetPos, float aSize)
Draw a round arrow.
glm::dvec2 SFVEC2D
Definition: xv3d_types.h:43
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44
constexpr int delta
const SFVEC2F & GetEnd_minus_Start() const
const SFVEC2F & GetStart() const
float GetWidth() const