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