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