Applied patch [ 1355355 ] Replace GPLed code in penguin sample and add features

(with Unicode and scope mods)
By Sandro Sigala


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36174 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2005-11-14 17:38:24 +00:00
parent 3d1a1d2df6
commit 4b764db379
20 changed files with 953 additions and 642 deletions

View File

@@ -855,7 +855,7 @@ SAMPLES_DIST: ALL_GUI_DIST
$(CP_P) $(SAMPDIR)/opengl/penguin/*.cpp $(DISTDIR)/samples/opengl/penguin
$(CP_P) $(SAMPDIR)/opengl/penguin/*.c $(DISTDIR)/samples/opengl/penguin
$(CP_P) $(SAMPDIR)/opengl/penguin/*.h $(DISTDIR)/samples/opengl/penguin
$(CP_P) $(SAMPDIR)/opengl/penguin/*.lwo $(DISTDIR)/samples/opengl/penguin
$(CP_P) $(SAMPDIR)/opengl/penguin/*.dxf.gz $(DISTDIR)/samples/opengl/penguin
mkdir $(DISTDIR)/samples/opengl/cube
$(CP_P) $(SAMPDIR)/opengl/cube/Makefile.in $(DISTDIR)/samples/opengl/cube
$(CP_P) $(SAMPDIR)/opengl/cube/makefile.unx $(DISTDIR)/samples/opengl/cube

View File

@@ -974,7 +974,7 @@ samples/opengl/penguin/*.xbm
samples/opengl/penguin/*.xpm
samples/opengl/penguin/*.pro
samples/opengl/penguin/make*.*
samples/opengl/penguin/penguin.lwo
samples/opengl/penguin/penguin.dxf.gz
samples/opengl/penguin/*.bkl
samples/png/*.cpp

View File

@@ -67,6 +67,7 @@ samples/propsize/Makefile.in
samples/regtest/Makefile.in
samples/render/Makefile.in
samples/richedit/Makefile.in
samples/richtext/Makefile.in
samples/rotate/Makefile.in
samples/sashtest/Makefile.in
samples/scroll/Makefile.in

View File

@@ -211,6 +211,9 @@ samples/render/*.dsw
samples/richedit/*.dsp
samples/richedit/*.dsw
samples/richtext/*.dsp
samples/richtext/*.dsw
samples/rotate/rotate.dsp
samples/rotate/rotate.dsw

View File

@@ -194,6 +194,9 @@ samples/render/render_render.vcw
samples/richedit/richedit.vcp
samples/richedit/richedit.vcw
samples/richtext/richtext.vcp
samples/richtext/richtext.vcw
samples/rotate/rotate.vcp
samples/rotate/rotate.vcw

View File

@@ -52,7 +52,7 @@ PENGUIN_CXXFLAGS = -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
PENGUIN_OBJECTS = \
$(__penguin_os2_lib_res) \
penguin_penguin.o \
penguin_lw.o \
penguin_dxfrenderer.o \
penguin_trackball.o \
$(__penguin___win32rc)
@@ -187,7 +187,7 @@ penguin.app/Contents/PkgInfo: $(__penguin___depname) $(top_srcdir)/src/mac/carbo
data:
@mkdir -p .
@for f in penguin.lwo; do \
@for f in penguin.dxf.gz; do \
if test ! -f ./$$f -a ! -d ./$$f ; \
then x=yep ; \
else x=`find $(srcdir)/$$f -newer ./$$f -print` ; \
@@ -200,8 +200,8 @@ data:
penguin_penguin.o: $(srcdir)/penguin.cpp
$(CXXC) -c -o $@ $(PENGUIN_CXXFLAGS) $(srcdir)/penguin.cpp
penguin_lw.o: $(srcdir)/lw.cpp
$(CXXC) -c -o $@ $(PENGUIN_CXXFLAGS) $(srcdir)/lw.cpp
penguin_dxfrenderer.o: $(srcdir)/dxfrenderer.cpp
$(CXXC) -c -o $@ $(PENGUIN_CXXFLAGS) $(srcdir)/dxfrenderer.cpp
penguin_trackball.o: $(srcdir)/trackball.c
$(CCC) -c -o $@ $(PENGUIN_CFLAGS) $(srcdir)/trackball.c

View File

@@ -0,0 +1,680 @@
/////////////////////////////////////////////////////////////////////////////
// Name: dxfrenderer.cpp
// Purpose: DXF reader and renderer
// Author: Sandro Sigala
// Modified by:
// Created: 2005-11-10
// RCS-ID: $Id$
// Copyright: (c) Sandro Sigala
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/wfstream.h"
#include "wx/txtstrm.h"
#if !wxUSE_GLCANVAS
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif
#ifdef __WXMAC__
# ifdef __DARWIN__
# include <OpenGL/glu.h>
# else
# include <glu.h>
# endif
#else
# include <GL/glu.h>
#endif
#include "dxfrenderer.h"
#include <wx/listimpl.cpp>
WX_DEFINE_LIST(DXFEntityList);
WX_DEFINE_LIST(DXFLayerList);
// Conversion table from AutoCAD ACI colours to RGB values
static const struct { unsigned char r, g, b; } aci_to_rgb[256] = {
/* 0 */ 255, 255, 255,
/* 1 */ 255, 0, 0,
/* 2 */ 255, 255, 0,
/* 3 */ 0, 255, 0,
/* 4 */ 0, 255, 255,
/* 5 */ 0, 0, 255,
/* 6 */ 255, 0, 255,
/* 7 */ 255, 255, 255,
/* 8 */ 128, 128, 128,
/* 9 */ 192, 192, 192,
/* 10 */ 255, 0, 0,
/* 11 */ 255, 127, 127,
/* 12 */ 204, 0, 0,
/* 13 */ 204, 102, 102,
/* 14 */ 153, 0, 0,
/* 15 */ 153, 76, 76,
/* 16 */ 127, 0, 0,
/* 17 */ 127, 63, 63,
/* 18 */ 76, 0, 0,
/* 19 */ 76, 38, 38,
/* 20 */ 255, 63, 0,
/* 21 */ 255, 159, 127,
/* 22 */ 204, 51, 0,
/* 23 */ 204, 127, 102,
/* 24 */ 153, 38, 0,
/* 25 */ 153, 95, 76,
/* 26 */ 127, 31, 0,
/* 27 */ 127, 79, 63,
/* 28 */ 76, 19, 0,
/* 29 */ 76, 47, 38,
/* 30 */ 255, 127, 0,
/* 31 */ 255, 191, 127,
/* 32 */ 204, 102, 0,
/* 33 */ 204, 153, 102,
/* 34 */ 153, 76, 0,
/* 35 */ 153, 114, 76,
/* 36 */ 127, 63, 0,
/* 37 */ 127, 95, 63,
/* 38 */ 76, 38, 0,
/* 39 */ 76, 57, 38,
/* 40 */ 255, 191, 0,
/* 41 */ 255, 223, 127,
/* 42 */ 204, 153, 0,
/* 43 */ 204, 178, 102,
/* 44 */ 153, 114, 0,
/* 45 */ 153, 133, 76,
/* 46 */ 127, 95, 0,
/* 47 */ 127, 111, 63,
/* 48 */ 76, 57, 0,
/* 49 */ 76, 66, 38,
/* 50 */ 255, 255, 0,
/* 51 */ 255, 255, 127,
/* 52 */ 204, 204, 0,
/* 53 */ 204, 204, 102,
/* 54 */ 153, 153, 0,
/* 55 */ 153, 153, 76,
/* 56 */ 127, 127, 0,
/* 57 */ 127, 127, 63,
/* 58 */ 76, 76, 0,
/* 59 */ 76, 76, 38,
/* 60 */ 191, 255, 0,
/* 61 */ 223, 255, 127,
/* 62 */ 153, 204, 0,
/* 63 */ 178, 204, 102,
/* 64 */ 114, 153, 0,
/* 65 */ 133, 153, 76,
/* 66 */ 95, 127, 0,
/* 67 */ 111, 127, 63,
/* 68 */ 57, 76, 0,
/* 69 */ 66, 76, 38,
/* 70 */ 127, 255, 0,
/* 71 */ 191, 255, 127,
/* 72 */ 102, 204, 0,
/* 73 */ 153, 204, 102,
/* 74 */ 76, 153, 0,
/* 75 */ 114, 153, 76,
/* 76 */ 63, 127, 0,
/* 77 */ 95, 127, 63,
/* 78 */ 38, 76, 0,
/* 79 */ 57, 76, 38,
/* 80 */ 63, 255, 0,
/* 81 */ 159, 255, 127,
/* 82 */ 51, 204, 0,
/* 83 */ 127, 204, 102,
/* 84 */ 38, 153, 0,
/* 85 */ 95, 153, 76,
/* 86 */ 31, 127, 0,
/* 87 */ 79, 127, 63,
/* 88 */ 19, 76, 0,
/* 89 */ 47, 76, 38,
/* 90 */ 0, 255, 0,
/* 91 */ 127, 255, 127,
/* 92 */ 0, 204, 0,
/* 93 */ 102, 204, 102,
/* 94 */ 0, 153, 0,
/* 95 */ 76, 153, 76,
/* 96 */ 0, 127, 0,
/* 97 */ 63, 127, 63,
/* 98 */ 0, 76, 0,
/* 99 */ 38, 76, 38,
/* 100 */ 0, 255, 63,
/* 101 */ 127, 255, 159,
/* 102 */ 0, 204, 51,
/* 103 */ 102, 204, 127,
/* 104 */ 0, 153, 38,
/* 105 */ 76, 153, 95,
/* 106 */ 0, 127, 31,
/* 107 */ 63, 127, 79,
/* 108 */ 0, 76, 19,
/* 109 */ 38, 76, 47,
/* 110 */ 0, 255, 127,
/* 111 */ 127, 255, 191,
/* 112 */ 0, 204, 102,
/* 113 */ 102, 204, 153,
/* 114 */ 0, 153, 76,
/* 115 */ 76, 153, 114,
/* 116 */ 0, 127, 63,
/* 117 */ 63, 127, 95,
/* 118 */ 0, 76, 38,
/* 119 */ 38, 76, 57,
/* 120 */ 0, 255, 191,
/* 121 */ 127, 255, 223,
/* 122 */ 0, 204, 153,
/* 123 */ 102, 204, 178,
/* 124 */ 0, 153, 114,
/* 125 */ 76, 153, 133,
/* 126 */ 0, 127, 95,
/* 127 */ 63, 127, 111,
/* 128 */ 0, 76, 57,
/* 129 */ 38, 76, 66,
/* 130 */ 0, 255, 255,
/* 131 */ 127, 255, 255,
/* 132 */ 0, 204, 204,
/* 133 */ 102, 204, 204,
/* 134 */ 0, 153, 153,
/* 135 */ 76, 153, 153,
/* 136 */ 0, 127, 127,
/* 137 */ 63, 127, 127,
/* 138 */ 0, 76, 76,
/* 139 */ 38, 76, 76,
/* 140 */ 0, 191, 255,
/* 141 */ 127, 223, 255,
/* 142 */ 0, 153, 204,
/* 143 */ 102, 178, 204,
/* 144 */ 0, 114, 153,
/* 145 */ 76, 133, 153,
/* 146 */ 0, 95, 127,
/* 147 */ 63, 111, 127,
/* 148 */ 0, 57, 76,
/* 149 */ 38, 66, 76,
/* 150 */ 0, 127, 255,
/* 151 */ 127, 191, 255,
/* 152 */ 0, 102, 204,
/* 153 */ 102, 153, 204,
/* 154 */ 0, 76, 153,
/* 155 */ 76, 114, 153,
/* 156 */ 0, 63, 127,
/* 157 */ 63, 95, 127,
/* 158 */ 0, 38, 76,
/* 159 */ 38, 57, 76,
/* 160 */ 0, 63, 255,
/* 161 */ 127, 159, 255,
/* 162 */ 0, 51, 204,
/* 163 */ 102, 127, 204,
/* 164 */ 0, 38, 153,
/* 165 */ 76, 95, 153,
/* 166 */ 0, 31, 127,
/* 167 */ 63, 79, 127,
/* 168 */ 0, 19, 76,
/* 169 */ 38, 47, 76,
/* 170 */ 0, 0, 255,
/* 171 */ 127, 127, 255,
/* 172 */ 0, 0, 204,
/* 173 */ 102, 102, 204,
/* 174 */ 0, 0, 153,
/* 175 */ 76, 76, 153,
/* 176 */ 0, 0, 127,
/* 177 */ 63, 63, 127,
/* 178 */ 0, 0, 76,
/* 179 */ 38, 38, 76,
/* 180 */ 63, 0, 255,
/* 181 */ 159, 127, 255,
/* 182 */ 51, 0, 204,
/* 183 */ 127, 102, 204,
/* 184 */ 38, 0, 153,
/* 185 */ 95, 76, 153,
/* 186 */ 31, 0, 127,
/* 187 */ 79, 63, 127,
/* 188 */ 19, 0, 76,
/* 189 */ 47, 38, 76,
/* 190 */ 127, 0, 255,
/* 191 */ 191, 127, 255,
/* 192 */ 102, 0, 204,
/* 193 */ 153, 102, 204,
/* 194 */ 76, 0, 153,
/* 195 */ 114, 76, 153,
/* 196 */ 63, 0, 127,
/* 197 */ 95, 63, 127,
/* 198 */ 38, 0, 76,
/* 199 */ 57, 38, 76,
/* 200 */ 191, 0, 255,
/* 201 */ 223, 127, 255,
/* 202 */ 153, 0, 204,
/* 203 */ 178, 102, 204,
/* 204 */ 114, 0, 153,
/* 205 */ 133, 76, 153,
/* 206 */ 95, 0, 127,
/* 207 */ 111, 63, 127,
/* 208 */ 57, 0, 76,
/* 209 */ 66, 38, 76,
/* 210 */ 255, 0, 255,
/* 211 */ 255, 127, 255,
/* 212 */ 204, 0, 204,
/* 213 */ 204, 102, 204,
/* 214 */ 153, 0, 153,
/* 215 */ 153, 76, 153,
/* 216 */ 127, 0, 127,
/* 217 */ 127, 63, 127,
/* 218 */ 76, 0, 76,
/* 219 */ 76, 38, 76,
/* 220 */ 255, 0, 191,
/* 221 */ 255, 127, 223,
/* 222 */ 204, 0, 153,
/* 223 */ 204, 102, 178,
/* 224 */ 153, 0, 114,
/* 225 */ 153, 76, 133,
/* 226 */ 127, 0, 95,
/* 227 */ 127, 63, 111,
/* 228 */ 76, 0, 57,
/* 229 */ 76, 38, 66,
/* 230 */ 255, 0, 127,
/* 231 */ 255, 127, 191,
/* 232 */ 204, 0, 102,
/* 233 */ 204, 102, 153,
/* 234 */ 153, 0, 76,
/* 235 */ 153, 76, 114,
/* 236 */ 127, 0, 63,
/* 237 */ 127, 63, 95,
/* 238 */ 76, 0, 38,
/* 239 */ 76, 38, 57,
/* 240 */ 255, 0, 63,
/* 241 */ 255, 127, 159,
/* 242 */ 204, 0, 51,
/* 243 */ 204, 102, 127,
/* 244 */ 153, 0, 38,
/* 245 */ 153, 76, 95,
/* 246 */ 127, 0, 31,
/* 247 */ 127, 63, 79,
/* 248 */ 76, 0, 19,
/* 249 */ 76, 38, 47,
/* 250 */ 51, 51, 51,
/* 251 */ 91, 91, 91,
/* 252 */ 132, 132, 132,
/* 253 */ 173, 173, 173,
/* 254 */ 214, 214, 214,
/* 255 */ 255, 255, 255,
};
inline DXFVector Cross(const DXFVector& v1, const DXFVector& v2)
{
return DXFVector(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
}
void DXFFace::CalculateNormal()
{
DXFVector v01, v02;
v01.x = v0.x - v1.x;
v01.y = v0.y - v1.y;
v01.z = v0.z - v1.z;
v02.x = v0.x - v2.x;
v02.y = v0.y - v2.y;
v02.z = v0.z - v2.z;
n = Cross(v01, v02);
float mod = sqrt(n.x*n.x + n.y*n.y + n.z*n.z);
n.x /= mod;
n.y /= mod;
n.z /= mod;
}
// convert an AutoCAD ACI colour to wxWidgets RGB colour
inline wxColour ACIColourToRGB(int col)
{
wxASSERT(col >= 0 && col <= 255);
return wxColour(aci_to_rgb[col].r, aci_to_rgb[col].g, aci_to_rgb[col].b);
}
// DXFReader constructor
DXFRenderer::DXFRenderer()
{
m_loaded = false;
}
// DXFReader destructor
DXFRenderer::~DXFRenderer()
{
Clear();
}
// deallocate all the dynamic data
void DXFRenderer::Clear()
{
m_loaded = false;
{
for (DXFLayerList::Node *node = m_layers.GetFirst(); node; node = node->GetNext())
{
DXFLayer *current = node->GetData();
delete current;
}
}
m_layers.Clear();
{
for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext())
{
DXFEntity *current = node->GetData();
delete current;
}
m_entities.Clear();
}
}
int DXFRenderer::GetLayerColour(const wxString& layer) const
{
for (DXFLayerList::Node *node = m_layers.GetFirst(); node; node = node->GetNext())
{
DXFLayer *current = node->GetData();
if (current->name == layer)
return current->colour;
}
return 7; // white
}
// read two sequential lines
inline void GetLines(wxTextInputStream& text, wxString& line1, wxString& line2)
{
line1 = text.ReadLine().Trim().Trim(false);
line2 = text.ReadLine().Trim().Trim(false);
}
// parse header section: just skip everything
bool DXFRenderer::ParseHeader(wxInputStream& stream)
{
wxTextInputStream text(stream);
wxString line1, line2;
while (stream.CanRead())
{
GetLines(text, line1, line2);
if (line1 == wxT("0") && line2 == wxT("ENDSEC"))
return true;
}
return false;
}
// parse tables section: save layers name and colour
bool DXFRenderer::ParseTables(wxInputStream& stream)
{
wxTextInputStream text(stream);
wxString line1, line2;
bool inlayer=false;
DXFLayer layer;
while (stream.CanRead())
{
GetLines(text, line1, line2);
if (line1 == wxT("0") && inlayer)
{
// flush layer
if (!layer.name.IsEmpty() && layer.colour != -1)
{
DXFLayer *p = new DXFLayer;
p->name = layer.name;
p->colour = layer.colour;
m_layers.Append(p);
}
layer = DXFLayer();
inlayer = false;
}
if (line1 == wxT("0") && line2 == wxT("ENDSEC"))
return true;
else if (line1 == wxT("0") && line2 == wxT("LAYER"))
inlayer = true;
else if (inlayer)
{
if (line1 == wxT("2")) // layer name
layer.name = line2;
else if (line1 == wxT("62")) // ACI colour
{
long l;
line2.ToLong(&l);
layer.colour = l;
}
}
}
return false;
}
// parse entities section: save 3DFACE and LINE entities
bool DXFRenderer::ParseEntities(wxInputStream& stream)
{
wxTextInputStream text(stream);
wxString line1, line2;
int state = 0; // 0: none, 1: 3DFACE, 2: LINE
DXFVector v[4];
int colour = -1;
wxString layer;
while (stream.CanRead())
{
GetLines(text, line1, line2);
if (line1 == wxT("0") && state > 0)
{
// flush entity
if (state == 1) // 3DFACE
{
DXFFace *p = new DXFFace;
p->v0 = v[0];
p->v1 = v[1];
p->v2 = v[2];
p->v3 = v[3];
p->CalculateNormal();
if (colour != -1)
p->colour = colour;
else
p->colour = GetLayerColour(layer);
m_entities.Append(p);
colour = -1; layer = wxEmptyString;
v[0] = v[1] = v[2] = v[3] = DXFVector();
state = 0;
}
else if (state == 2) // LINE
{
DXFLine *p = new DXFLine;
p->v0 = v[0];
p->v1 = v[1];
if (colour != -1)
p->colour = colour;
else
p->colour = GetLayerColour(layer);
m_entities.Append(p);
colour = -1; layer = wxEmptyString;
v[0] = v[1] = v[2] = v[3] = DXFVector();
state = 0;
}
}
if (line1 == wxT("0") && line2 == wxT("ENDSEC"))
return true;
else if (line1 == wxT("0") && line2 == wxT("3DFACE"))
state = 1;
else if (line1 == wxT("0") && line2 == wxT("LINE"))
state = 2;
else if (state > 0)
{
double d;
line2.ToDouble(&d);
if (line1 == wxT("10"))
v[0].x = d;
else if (line1 == wxT("20"))
v[0].y = d;
else if (line1 == wxT("30"))
v[0].z = d;
else if (line1 == wxT("11"))
v[1].x = d;
else if (line1 == wxT("21"))
v[1].y = d;
else if (line1 == wxT("31"))
v[1].z = d;
else if (line1 == wxT("12"))
v[2].x = d;
else if (line1 == wxT("22"))
v[2].y = d;
else if (line1 == wxT("32"))
v[2].z = d;
else if (line1 == wxT("13"))
v[3].x = d;
else if (line1 == wxT("23"))
v[3].y = d;
else if (line1 == wxT("33"))
v[3].z = d;
else if (line1 == wxT("8")) // layer
layer = line2;
else if (line1 == wxT("62")) // colour
{
long l;
line2.ToLong(&l);
colour = l;
}
}
}
return false;
}
// parse and load a DXF file
// currently pretty limited, but knows enought do handle 3DFACEs and LINEs
bool DXFRenderer::Load(wxInputStream& stream)
{
Clear();
wxTextInputStream text(stream);
wxString line1, line2;
while (stream.CanRead())
{
GetLines(text, line1, line2);
if (line1 == wxT("999")) // comment
continue;
else if (line1 == wxT("0") && line2 == wxT("SECTION"))
{
GetLines(text, line1, line2);
if (line1 == wxT("2"))
{
if (line2 == wxT("HEADER"))
{
if (!ParseHeader(stream))
return false;
}
else if (line2 == wxT("TABLES"))
{
if (!ParseTables(stream))
return false;
}
else if (line2 == wxT("ENTITIES"))
{
if (!ParseEntities(stream))
return false;
}
}
}
}
NormalizeEntities();
m_loaded = true;
return true;
}
inline float mymin(float x, float y) { return x < y ? x : y; }
inline float mymax(float x, float y) { return x > y ? x : y; }
// Scale object boundings to [-5,5]
void DXFRenderer::NormalizeEntities()
{
// calculate current min and max boundings of object
DXFVector minv(10e20f, 10e20f, 10e20f);
DXFVector maxv(-10e20f, -10e20f, -10e20f);
for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext())
{
DXFEntity *p = node->GetData();
if (p->type == DXFEntity::Line)
{
DXFLine *line = (DXFLine *)p;
const DXFVector *v[2] = { &line->v0, &line->v1 };
for (int i = 0; i < 2; ++i)
{
minv.x = mymin(v[i]->x, minv.x);
minv.y = mymin(v[i]->y, minv.y);
minv.z = mymin(v[i]->z, minv.z);
maxv.x = mymax(v[i]->x, maxv.x);
maxv.y = mymax(v[i]->y, maxv.y);
maxv.z = mymax(v[i]->z, maxv.z);
}
} else if (p->type == DXFEntity::Face)
{
DXFFace *face = (DXFFace *)p;
const DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 };
for (int i = 0; i < 4; ++i)
{
minv.x = mymin(v[i]->x, minv.x);
minv.y = mymin(v[i]->y, minv.y);
minv.z = mymin(v[i]->z, minv.z);
maxv.x = mymax(v[i]->x, maxv.x);
maxv.y = mymax(v[i]->y, maxv.y);
maxv.z = mymax(v[i]->z, maxv.z);
}
}
}
// rescale object down to [-5,5]
DXFVector span(maxv.x - minv.x, maxv.y - minv.y, maxv.z - minv.z);
float factor = mymin(mymin(10.0f / span.x, 10.0f / span.y), 10.0f / span.z);
for (DXFEntityList::Node *node2 = m_entities.GetFirst(); node2; node2 = node2->GetNext())
{
DXFEntity *p = node2->GetData();
if (p->type == DXFEntity::Line)
{
DXFLine *line = (DXFLine *)p;
DXFVector *v[2] = { &line->v0, &line->v1 };
for (int i = 0; i < 2; ++i)
{
v[i]->x -= minv.x + span.x/2; v[i]->x *= factor;
v[i]->y -= minv.y + span.y/2; v[i]->y *= factor;
v[i]->z -= minv.z + span.z/2; v[i]->z *= factor;
}
} else if (p->type == DXFEntity::Face)
{
DXFFace *face = (DXFFace *)p;
DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 };
for (int i = 0; i < 4; ++i)
{
v[i]->x -= minv.x + span.x/2; v[i]->x *= factor;
v[i]->y -= minv.y + span.y/2; v[i]->y *= factor;
v[i]->z -= minv.z + span.z/2; v[i]->z *= factor;
}
}
}
}
// OpenGL renderer for DXF entities
void DXFRenderer::Render() const
{
if (!m_loaded)
return;
for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext())
{
DXFEntity *p = node->GetData();
wxColour c = ACIColourToRGB(p->colour);
if (p->type == DXFEntity::Line)
{
DXFLine *line = (DXFLine *)p;
glBegin(GL_LINES);
glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0);
glVertex3f(line->v0.x, line->v0.y, line->v0.z);
glVertex3f(line->v1.x, line->v1.y, line->v1.z);
glEnd();
}
else if (p->type == DXFEntity::Face)
{
DXFFace *face = (DXFFace *)p;
glBegin(GL_TRIANGLES);
glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0);
glNormal3f(face->n.x, face->n.y, face->n.z);
glVertex3f(face->v0.x, face->v0.y, face->v0.z);
glVertex3f(face->v1.x, face->v1.y, face->v1.z);
glVertex3f(face->v2.x, face->v2.y, face->v2.z);
glEnd();
}
}
}

View File

@@ -0,0 +1,79 @@
/////////////////////////////////////////////////////////////////////////////
// Name: dxfrenderer.h
// Purpose: DXF reader and renderer
// Author: Sandro Sigala
// Modified by:
// Created: 2005-11-10
// RCS-ID: $Id$
// Copyright: (c) Sandro Sigala
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _DXFRENDERER_H_
#define _DXFRENDERER_H_
struct DXFVector
{
DXFVector() { x = y = z = 0.0f; }
DXFVector(float _x, float _y, float _z) { x = _x; y = _y; z = _z; }
float x, y, z;
};
struct DXFEntity
{
enum Type { Line, Face } type;
int colour;
};
struct DXFLine: public DXFEntity
{
DXFLine() { type = Line; }
DXFVector v0;
DXFVector v1;
};
struct DXFFace: public DXFEntity
{
DXFFace() { type = Face; }
void CalculateNormal();
DXFVector v0;
DXFVector v1;
DXFVector v2;
DXFVector v3;
DXFVector n; // normal
};
struct DXFLayer
{
DXFLayer() { colour = -1; }
wxString name;
int colour;
};
WX_DECLARE_LIST(DXFEntity, DXFEntityList);
WX_DECLARE_LIST(DXFLayer, DXFLayerList);
class DXFRenderer
{
public:
DXFRenderer();
~DXFRenderer();
void Clear();
bool Load(wxInputStream& stream);
bool IsOk() const { return m_loaded; }
void Render() const;
private:
bool ParseHeader(wxInputStream& stream);
bool ParseTables(wxInputStream& stream);
bool ParseEntities(wxInputStream& stream);
int GetLayerColour(const wxString& layer) const;
void NormalizeEntities();
bool m_loaded;
DXFLayerList m_layers;
DXFEntityList m_entities;
};
#endif // !_DXFRENDERER_H_

View File

@@ -1,438 +0,0 @@
/*
* Copyright (C) 1998 Janne L<>f <jlof@mail.student.oulu.fi>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#ifdef __WXMSW__
#include <windows.h>
#endif
#include "lw.h"
#include <stdlib.h>
#include <stdio.h>
#if wxUSE_GLCANVAS
#define MK_ID(a,b,c,d) ((((wxUint32)(a))<<24)| \
(((wxUint32)(b))<<16)| \
(((wxUint32)(c))<< 8)| \
(((wxUint32)(d)) ))
#define ID_FORM MK_ID('F','O','R','M')
#define ID_LWOB MK_ID('L','W','O','B')
#define ID_PNTS MK_ID('P','N','T','S')
#define ID_SRFS MK_ID('S','R','F','S')
#define ID_SURF MK_ID('S','U','R','F')
#define ID_POLS MK_ID('P','O','L','S')
#define ID_COLR MK_ID('C','O','L','R')
static wxInt32 read_char(FILE *f)
{
int c = fgetc(f);
return c;
}
static wxInt32 read_short(FILE *f)
{
// the execution path was not always correct
// when using the direct evaluation in the return statement
wxInt32 first = read_char(f) ;
wxInt32 second = read_char(f) ;
return (first<<8) | second ;
}
static wxInt32 read_long(FILE *f)
{
// the execution path was not always correct
// when using the direct evaluation in the return statement
wxInt32 first = read_char(f) ;
wxInt32 second = read_char(f) ;
wxInt32 third = read_char(f) ;
wxInt32 fourth = read_char(f) ;
return (first<<24) | (second<<16) | (third<<8) | fourth ;
}
static GLfloat read_float(FILE *f)
{
wxInt32 x = read_long(f);
return *(GLfloat*)&x;
}
static int read_string(FILE *f, char *s)
{
int c;
int cnt = 0;
do {
c = read_char(f);
if (cnt < LW_MAX_NAME_LEN)
s[cnt] = (char)c;
else
s[LW_MAX_NAME_LEN-1] = 0;
cnt++;
} while (c != 0);
/* if length of string (including \0) is odd skip another byte */
if (cnt%2) {
read_char(f);
cnt++;
}
return cnt;
}
static void read_srfs(FILE *f, int nbytes, lwObject *lwo)
{
int guess_cnt = lwo->material_cnt;
while (nbytes > 0) {
lwMaterial *material;
/* allocate more memory for materials if needed */
if (guess_cnt <= lwo->material_cnt) {
guess_cnt += guess_cnt/2 + 4;
lwo->material = (lwMaterial*) realloc(lwo->material, sizeof(lwMaterial)*guess_cnt);
}
material = lwo->material + lwo->material_cnt++;
/* read name */
nbytes -= read_string(f,material->name);
/* defaults */
material->r = 0.7f;
material->g = 0.7f;
material->b = 0.7f;
}
lwo->material = (lwMaterial*) realloc(lwo->material, sizeof(lwMaterial)*lwo->material_cnt);
}
static void read_surf(FILE *f, int nbytes, lwObject *lwo)
{
int i;
char name[LW_MAX_NAME_LEN];
lwMaterial *material = NULL;
/* read surface name */
nbytes -= read_string(f,name);
/* find material */
for (i=0; i< lwo->material_cnt; i++) {
if (strcmp(lwo->material[i].name,name) == 0) {
material = &lwo->material[i];
break;
}
}
/* read values */
while (nbytes > 0) {
int id = read_long(f);
int len = read_short(f);
nbytes -= 6 + len + (len%2);
switch (id) {
case ID_COLR:
material->r = read_char(f) / 255.0;
material->g = read_char(f) / 255.0;
material->b = read_char(f) / 255.0;
read_char(f); /* dummy */
break;
default:
fseek(f, len+(len%2), SEEK_CUR);
}
}
}
static void read_pols(FILE *f, int nbytes, lwObject *lwo)
{
int guess_cnt = lwo->face_cnt;
while (nbytes > 0) {
lwFace *face;
int i;
/* allocate more memory for polygons if necessary */
if (guess_cnt <= lwo->face_cnt) {
guess_cnt += guess_cnt + 4;
lwo->face = (lwFace*) realloc((void*) lwo->face, sizeof(lwFace)*guess_cnt);
}
face = lwo->face + lwo->face_cnt++;
/* number of points in this face */
face->index_cnt = read_short(f);
nbytes -= 2;
/* allocate space for points */
face->index = (int*) calloc(sizeof(int)*face->index_cnt,1);
/* read points in */
for (i=0; i<face->index_cnt; i++) {
face->index[i] = read_short(f);
nbytes -= 2;
}
/* read surface material */
face->material = read_short(f);
nbytes -= 2;
/* skip over detail polygons */
if (face->material < 0) {
int det_cnt;
face->material = -face->material;
det_cnt = read_short(f);
nbytes -= 2;
while (det_cnt-- > 0) {
int cnt = read_short(f);
fseek(f, cnt*2+2, SEEK_CUR);
nbytes -= cnt*2+2;
}
}
face->material -= 1;
}
/* readjust to true size */
lwo->face = (lwFace*) realloc(lwo->face, sizeof(lwFace)*lwo->face_cnt);
}
static void read_pnts(FILE *f, int nbytes, lwObject *lwo)
{
int i;
lwo->vertex_cnt = nbytes / 12;
lwo->vertex = (float*) calloc(sizeof(GLfloat)*lwo->vertex_cnt*3, 1);
for (i=0; i<lwo->vertex_cnt; i++) {
lwo->vertex[i*3+0] = read_float(f);
lwo->vertex[i*3+1] = read_float(f);
lwo->vertex[i*3+2] = read_float(f);
}
}
bool lw_is_lwobject(const char *lw_file)
{
FILE *f = fopen(lw_file, "rb");
if (f) {
wxInt32 form = read_long(f);
wxInt32 nlen = read_long(f);
wxInt32 lwob = read_long(f);
fclose(f);
if (form == ID_FORM && nlen != 0 && lwob == ID_LWOB)
return true;
}
return false;
}
lwObject *lw_object_read(const char *lw_file)
{
/* open file */
FILE *f = fopen(lw_file, "rb");
if (f == NULL) {
return NULL;
}
/* check for headers */
if (read_long(f) != ID_FORM) {
fclose(f);
return NULL;
}
wxInt32 read_bytes = 0;
wxInt32 form_bytes = read_long(f);
read_bytes += 4;
if (read_long(f) != ID_LWOB) {
fclose(f);
return NULL;
}
/* create new lwObject */
lwObject *lw_object = (lwObject*) calloc(sizeof(lwObject),1);
/* read chunks */
while (read_bytes < form_bytes) {
wxInt32 id = read_long(f);
wxInt32 nbytes = read_long(f);
read_bytes += 8 + nbytes + (nbytes%2);
switch (id) {
case ID_PNTS:
read_pnts(f, nbytes, lw_object);
break;
case ID_POLS:
read_pols(f, nbytes, lw_object);
break;
case ID_SRFS:
read_srfs(f, nbytes, lw_object);
break;
case ID_SURF:
read_surf(f, nbytes, lw_object);
break;
default:
fseek(f, nbytes + (nbytes%2), SEEK_CUR);
}
}
fclose(f);
return lw_object;
}
void lw_object_free(lwObject *lw_object)
{
if (lw_object->face) {
int i;
for (i=0; i<lw_object->face_cnt; i++)
free(lw_object->face[i].index);
free(lw_object->face);
}
free(lw_object->material);
free(lw_object->vertex);
free(lw_object);
}
#define PX(i) (lw_object->vertex[face->index[i]*3+0])
#define PY(i) (lw_object->vertex[face->index[i]*3+1])
#define PZ(i) (lw_object->vertex[face->index[i]*3+2])
void lw_object_show(const lwObject *lw_object)
{
int i,j;
int prev_index_cnt = -1;
int prev_material = -1;
GLfloat prev_nx = 0;
GLfloat prev_ny = 0;
GLfloat prev_nz = 0;
for (i=0; i<lw_object->face_cnt; i++) {
GLfloat ax,ay,az,bx,by,bz,nx,ny,nz,r;
const lwFace *face = lw_object->face+i;
/* ignore faces with less than 3 points */
if (face->index_cnt < 3)
continue;
/* calculate normal */
ax = PX(1) - PX(0);
ay = PY(1) - PY(0);
az = PZ(1) - PZ(0);
bx = PX(face->index_cnt-1) - PX(0);
by = PY(face->index_cnt-1) - PY(0);
bz = PZ(face->index_cnt-1) - PZ(0);
nx = ay * bz - az * by;
ny = az * bx - ax * bz;
nz = ax * by - ay * bx;
r = sqrt(nx*nx + ny*ny + nz*nz);
if (r < 0.000001) /* avoid division by zero */
continue;
nx /= r;
ny /= r;
nz /= r;
/* glBegin/glEnd */
if (prev_index_cnt != face->index_cnt || prev_index_cnt > 4) {
if (prev_index_cnt > 0) glEnd();
prev_index_cnt = face->index_cnt;
switch (face->index_cnt) {
case 3:
glBegin(GL_TRIANGLES);
break;
case 4:
glBegin(GL_QUADS);
break;
default:
glBegin(GL_POLYGON);
}
}
/* update material if necessary */
if (prev_material != face->material) {
prev_material = face->material;
glColor3f(lw_object->material[face->material].r,
lw_object->material[face->material].g,
lw_object->material[face->material].b);
}
/* update normal if necessary */
if (nx != prev_nx || ny != prev_ny || nz != prev_nz) {
prev_nx = nx;
prev_ny = ny;
prev_nz = nz;
glNormal3f(nx,ny,nz);
}
/* draw polygon/triangle/quad */
for (j=0; j<face->index_cnt; j++)
glVertex3f(PX(j),PY(j),PZ(j));
}
/* if glBegin was called call glEnd */
if (prev_index_cnt > 0)
glEnd();
}
GLfloat lw_object_radius(const lwObject *lwo)
{
int i;
double max_radius = 0.0;
for (i=0; i<lwo->vertex_cnt; i++) {
GLfloat *v = &lwo->vertex[i*3];
double r = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
if (r > max_radius)
max_radius = r;
}
return sqrt(max_radius);
}
void lw_object_scale(lwObject *lwo, GLfloat scale)
{
int i;
for (i=0; i<lwo->vertex_cnt; i++) {
lwo->vertex[i*3+0] *= scale;
lwo->vertex[i*3+1] *= scale;
lwo->vertex[i*3+2] *= scale;
}
}
#endif

View File

@@ -1,79 +0,0 @@
/*
* Copyright (C) 1998 Janne L<>f <jlof@mail.student.oulu.fi>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LW_H
#define LW_H
#ifdef __WXMAC__
# ifdef __DARWIN__
# include <OpenGL/glu.h>
# else
# include <glu.h>
# endif
#else
# include <GL/glu.h>
#endif
#define LW_MAX_POINTS 200
#define LW_MAX_NAME_LEN 500
typedef struct {
char name[LW_MAX_NAME_LEN];
GLfloat r,g,b;
} lwMaterial;
typedef struct {
int material; /* material of this face */
int index_cnt; /* number of vertices */
int *index; /* index to vertex */
float *texcoord; /* u,v texture coordinates */
} lwFace;
typedef struct {
int face_cnt;
lwFace *face;
int material_cnt;
lwMaterial *material;
int vertex_cnt;
GLfloat *vertex;
} lwObject;
#ifdef __cplusplus
extern "C" {
#endif
#if wxUSE_GLCANVAS
bool lw_is_lwobject(const char *lw_file);
lwObject *lw_object_read(const char *lw_file);
void lw_object_free( lwObject *lw_object);
void lw_object_show(const lwObject *lw_object);
GLfloat lw_object_radius(const lwObject *lw_object);
void lw_object_scale (lwObject *lw_object, GLfloat scale);
#endif
#ifdef __cplusplus
}
#endif
#endif /* LW_H */

View File

@@ -41,7 +41,7 @@ PENGUIN_CXXFLAGS = $(__RUNTIME_LIBS_7) -I$(BCCDIR)\include $(__DEBUGINFO) \
-DNOPCH $(CPPFLAGS) $(CXXFLAGS)
PENGUIN_OBJECTS = \
$(OBJS)\penguin_penguin.obj \
$(OBJS)\penguin_lw.obj \
$(OBJS)\penguin_dxfrenderer.obj \
$(OBJS)\penguin_trackball.obj
### Conditionally set variables: ###
@@ -232,12 +232,12 @@ $(OBJS)\penguin.exe: $(PENGUIN_OBJECTS) $(OBJS)\penguin_penguin.res
data:
if not exist $(OBJS) mkdir $(OBJS)
for %f in (penguin.lwo) do if not exist $(OBJS)\%f copy .\%f $(OBJS)
for %f in (penguin.dxf.gz) do if not exist $(OBJS)\%f copy .\%f $(OBJS)
$(OBJS)\penguin_penguin.obj: .\penguin.cpp
$(CXX) -q -c -P -o$@ $(PENGUIN_CXXFLAGS) $**
$(OBJS)\penguin_lw.obj: .\lw.cpp
$(OBJS)\penguin_dxfrenderer.obj: .\dxfrenderer.cpp
$(CXX) -q -c -P -o$@ $(PENGUIN_CXXFLAGS) $**
$(OBJS)\penguin_trackball.obj: .\trackball.c

View File

@@ -34,7 +34,7 @@ PENGUIN_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG_2) $(__THREADSFLAG) \
-Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS)
PENGUIN_OBJECTS = \
$(OBJS)\penguin_penguin.o \
$(OBJS)\penguin_lw.o \
$(OBJS)\penguin_dxfrenderer.o \
$(OBJS)\penguin_trackball.o \
$(OBJS)\penguin_penguin_rc.o
@@ -225,12 +225,12 @@ endif
data:
if not exist $(OBJS) mkdir $(OBJS)
for %%f in (penguin.lwo) do if not exist $(OBJS)\%%f copy .\%%f $(OBJS)
for %%f in (penguin.dxf.gz) do if not exist $(OBJS)\%%f copy .\%%f $(OBJS)
$(OBJS)\penguin_penguin.o: ./penguin.cpp
$(CXX) -c -o $@ $(PENGUIN_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\penguin_lw.o: ./lw.cpp
$(OBJS)\penguin_dxfrenderer.o: ./dxfrenderer.cpp
$(CXX) -c -o $@ $(PENGUIN_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\penguin_trackball.o: ./trackball.c

View File

@@ -35,7 +35,7 @@ PENGUIN_CXXFLAGS = /M$(__RUNTIME_LIBS_8)$(__DEBUGRUNTIME_3) /DWIN32 \
$(CPPFLAGS) $(CXXFLAGS)
PENGUIN_OBJECTS = \
$(OBJS)\penguin_penguin.obj \
$(OBJS)\penguin_lw.obj \
$(OBJS)\penguin_dxfrenderer.obj \
$(OBJS)\penguin_trackball.obj \
$(OBJS)\penguin_penguin.res
@@ -302,12 +302,12 @@ $(OBJS)\penguin.exe: $(PENGUIN_OBJECTS) $(OBJS)\penguin_penguin.res
data:
if not exist $(OBJS) mkdir $(OBJS)
for %f in (penguin.lwo) do if not exist $(OBJS)\%f copy .\%f $(OBJS)
for %f in (penguin.dxf.gz) do if not exist $(OBJS)\%f copy .\%f $(OBJS)
$(OBJS)\penguin_penguin.obj: .\penguin.cpp
$(CXX) /c /nologo /TP /Fo$@ $(PENGUIN_CXXFLAGS) $**
$(OBJS)\penguin_lw.obj: .\lw.cpp
$(OBJS)\penguin_dxfrenderer.obj: .\dxfrenderer.cpp
$(CXX) /c /nologo /TP /Fo$@ $(PENGUIN_CXXFLAGS) $**
$(OBJS)\penguin_trackball.obj: .\trackball.c

View File

@@ -225,7 +225,7 @@ PENGUIN_CXXFLAGS = $(__DEBUGINFO_0) $(__OPTIMIZEFLAG_2) $(__THREADSFLAG_5) &
$(__RTTIFLAG_7) $(__EXCEPTIONSFLAG_8) $(CPPFLAGS) $(CXXFLAGS)
PENGUIN_OBJECTS = &
$(OBJS)\penguin_penguin.obj &
$(OBJS)\penguin_lw.obj &
$(OBJS)\penguin_dxfrenderer.obj &
$(OBJS)\penguin_trackball.obj
@@ -260,16 +260,16 @@ $(OBJS)\penguin.exe : $(PENGUIN_OBJECTS) $(OBJS)\penguin_penguin.res
data : .SYMBOLIC
if not exist $(OBJS) mkdir $(OBJS)
for %f in (penguin.lwo) do if not exist $(OBJS)\%f copy .\%f $(OBJS)
for %f in (penguin.dxf.gz) do if not exist $(OBJS)\%f copy .\%f $(OBJS)
$(OBJS)\penguin_penguin.obj : .AUTODEPEND .\penguin.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(PENGUIN_CXXFLAGS) $<
$(CXX) -zq -fo=$^@ $(PENGUIN_CXXFLAGS) $<
$(OBJS)\penguin_lw.obj : .AUTODEPEND .\lw.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(PENGUIN_CXXFLAGS) $<
$(OBJS)\penguin_dxfrenderer.obj : .AUTODEPEND .\dxfrenderer.cpp
$(CXX) -zq -fo=$^@ $(PENGUIN_CXXFLAGS) $<
$(OBJS)\penguin_trackball.obj : .AUTODEPEND .\trackball.c
$(CC) -bt=nt -zq -fo=$^@ $(PENGUIN_CFLAGS) $<
$(CC) -zq -fo=$^@ $(PENGUIN_CFLAGS) $<
$(OBJS)\penguin_penguin.res : .AUTODEPEND .\penguin.rc
wrc -q -ad -bt=nt -r -fo=$^@ -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) -i=.\..\..\..\include -i=$(SETUPHDIR) -i=. $(__DLLFLAG_p) -i=.\..\..\..\samples -dNOPCH $<

View File

@@ -8,7 +8,7 @@
<exe id="penguin" template="wx_sample" template_append="wx_append" cond="USE_OPENGL=='1'">
<sources>
penguin.cpp
lw.cpp
dxfrenderer.cpp
trackball.c
</sources>
<wx-lib>gl</wx-lib>
@@ -19,7 +19,7 @@
<wx-data id="data">
<files>
penguin.lwo
penguin.dxf.gz
</files>
</wx-data>

View File

@@ -2,7 +2,7 @@
// Name: penguin.cpp
// Purpose: wxGLCanvas demo program
// Author: Robert Roebling
// Modified by:
// Modified by: Sandro Sigala
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) Robert Roebling
@@ -37,28 +37,24 @@
#include "../../sample.xpm"
#define VIEW_ASPECT 1.3
// ---------------------------------------------------------------------------
// MyApp
// ---------------------------------------------------------------------------
// `Main program' equivalent, creating windows and returning main app frame
bool MyApp::OnInit()
{
// Create the main frame window
MyFrame *frame = new MyFrame(NULL, wxT("wxWidgets OpenGL Penguin Sample"),
MyFrame *frame = new MyFrame(NULL, wxT("wxWidgets Penguin Sample"),
wxDefaultPosition, wxDefaultSize);
/* Make a menubar */
wxMenu *fileMenu = new wxMenu;
fileMenu->Append(wxID_EXIT, wxT("E&xit"));
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(fileMenu, wxT("&File"));
frame->SetMenuBar(menuBar);
frame->SetCanvas( new TestGLCanvas(frame, wxID_ANY, wxDefaultPosition,
wxSize(200, 200), wxSUNKEN_BORDER) );
/* Load file wiht mesh data */
frame->GetCanvas()->LoadLWO( wxT("penguin.lwo") );
#if wxUSE_ZLIB
if (wxFileExists(wxT("penguin.dxf.gz")))
frame->GetCanvas()->LoadDXF(wxT("penguin.dxf.gz"));
#else
if (wxFileExists(wxT("penguin.dxf")))
frame->GetCanvas()->LoadDXF(wxT("penguin.dxf"));
#endif
/* Show the frame */
frame->Show(true);
@@ -68,26 +64,75 @@ bool MyApp::OnInit()
IMPLEMENT_APP(MyApp)
// ---------------------------------------------------------------------------
// MyFrame
// ---------------------------------------------------------------------------
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
EVT_MENU(wxID_OPEN, MyFrame::OnMenuFileOpen)
EVT_MENU(wxID_EXIT, MyFrame::OnMenuFileExit)
EVT_MENU(wxID_HELP, MyFrame::OnMenuHelpAbout)
END_EVENT_TABLE()
/* My frame constructor */
// MyFrame constructor
MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
const wxSize& size, long style)
: wxFrame(frame, wxID_ANY, title, pos, size, style)
{
m_canvas = NULL;
SetIcon(wxIcon(sample_xpm));
// Make the "File" menu
wxMenu *fileMenu = new wxMenu;
fileMenu->Append(wxID_OPEN, wxT("&Open..."));
fileMenu->AppendSeparator();
fileMenu->Append(wxID_EXIT, wxT("E&xit\tALT-X"));
// Make the "Help" menu
wxMenu *helpMenu = new wxMenu;
helpMenu->Append(wxID_HELP, wxT("&About..."));
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(fileMenu, wxT("&File"));
menuBar->Append(helpMenu, wxT("&Help"));
SetMenuBar(menuBar);
m_canvas = new TestGLCanvas(this, wxID_ANY, wxDefaultPosition,
wxSize(300, 300), wxSUNKEN_BORDER);
}
/* Intercept menu commands */
void MyFrame::OnExit( wxCommandEvent& WXUNUSED(event) )
// File|Open... command
void MyFrame::OnMenuFileOpen( wxCommandEvent& WXUNUSED(event) )
{
wxString filename = wxFileSelector(wxT("Choose DXF Model"), wxT(""), wxT(""), wxT(""),
#if wxUSE_ZLIB
wxT("DXF Drawing (*.dxf;*.dxf.gz)|*.dxf;*.dxf.gz|All files (*.*)|*.*"),
#else
wxT("DXF Drawing (*.dxf)|*.dxf)|All files (*.*)|*.*"),
#endif
wxOPEN);
if (!filename.IsEmpty())
{
m_canvas->LoadDXF(filename);
m_canvas->Refresh(false);
}
}
// File|Exit command
void MyFrame::OnMenuFileExit( wxCommandEvent& WXUNUSED(event) )
{
// true is to force the frame to close
Close(true);
}
// Help|About... command
void MyFrame::OnMenuHelpAbout( wxCommandEvent& WXUNUSED(event) )
{
wxMessageBox(wxT("OpenGL Penguin Sample (c) Robert Roebling, Sandro Sigala et al"));
}
// ---------------------------------------------------------------------------
// TestGLCanvas
// ---------------------------------------------------------------------------
BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
EVT_SIZE(TestGLCanvas::OnSize)
EVT_PAINT(TestGLCanvas::OnPaint)
@@ -99,18 +144,22 @@ TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name)
{
block = false;
m_gldata.initialized = false;
// initialize view matrix
m_gldata.beginx = 0.0f;
m_gldata.beginy = 0.0f;
m_gldata.zoom = 45.0f;
trackball(m_gldata.quat, 0.0f, 0.0f, 0.0f, 0.0f);
}
TestGLCanvas::~TestGLCanvas()
{
/* destroy mesh */
lw_object_free(info.lwobject);
}
void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
{
/* must always be here */
// must always be here
wxPaintDC dc(this);
#ifndef __WXMOTIF__
@@ -120,31 +169,25 @@ void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
SetCurrent();
// Initialize OpenGL
if (info.do_init)
if (!m_gldata.initialized)
{
InitGL();
info.do_init = false;
ResetProjectionMode();
m_gldata.initialized = true;
}
// View
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( info.zoom, VIEW_ASPECT, 1.0, 100.0 );
glMatrixMode( GL_MODELVIEW );
// Clear
glClearColor( 0.3f, 0.4f, 0.6f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Transformations
GLfloat m[4][4];
glLoadIdentity();
glTranslatef( 0.0f, 0.0f, -30.0f );
build_rotmatrix( m,info.quat );
glTranslatef( 0.0f, 0.0f, -20.0f );
GLfloat m[4][4];
build_rotmatrix( m, m_gldata.quat );
glMultMatrixf( &m[0][0] );
// Draw object
lw_object_show( info.lwobject );
m_renderer.Render();
// Flush
glFlush();
@@ -157,67 +200,61 @@ void TestGLCanvas::OnSize(wxSizeEvent& event)
{
// this is also necessary to update the context on some platforms
wxGLCanvas::OnSize(event);
// set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
int w, h;
GetClientSize(&w, &h);
#ifndef __WXMOTIF__
if ( GetContext() )
#endif
{
SetCurrent();
glViewport(0, 0, (GLint) w, (GLint) h);
}
// Reset the OpenGL view aspect
ResetProjectionMode();
}
void TestGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
{
/* Do nothing, to avoid flashing on MSW */
// Do nothing, to avoid flashing on MSW
}
void TestGLCanvas::LoadLWO(const wxString &filename)
// Load the DXF file. If the zlib support is compiled in wxWidgets,
// supports also the ".dxf.gz" gzip compressed files.
void TestGLCanvas::LoadDXF(const wxString& filename)
{
/* test if lightwave object */
if (!lw_is_lwobject(filename.mb_str())) return;
/* read lightwave object */
lwObject *lwobject = lw_object_read(filename.mb_str());
/* scale */
lw_object_scale(lwobject, 10.0 / lw_object_radius(lwobject));
/* set up mesh info */
info.do_init = true;
info.lwobject = lwobject;
info.beginx = 0.0f;
info.beginy = 0.0f;
info.zoom = 45.0f;
trackball( info.quat, 0.0f, 0.0f, 0.0f, 0.0f );
}
void TestGLCanvas::OnMouse( wxMouseEvent& event )
{
if ( event.Dragging() )
wxFileInputStream stream(filename);
if (stream.Ok())
#if wxUSE_ZLIB
{
wxSize sz( GetClientSize() );
if (filename.Right(3).Lower() == wxT(".gz"))
{
wxZlibInputStream zstream(stream);
m_renderer.Load(zstream);
} else
{
m_renderer.Load(stream);
}
}
#else
{
m_renderer.Load(stream);
}
#endif
}
void TestGLCanvas::OnMouse(wxMouseEvent& event)
{
if (event.Dragging())
{
wxSize sz(GetClientSize());
/* drag in progress, simulate trackball */
float spin_quat[4];
trackball(spin_quat,
(2.0*info.beginx - sz.x) / sz.x,
( sz.y - 2.0*info.beginy) / sz.y,
( 2.0*event.GetX() - sz.x) / sz.x,
( sz.y - 2.0*event.GetY()) / sz.y);
(2.0*m_gldata.beginx - sz.x) / sz.x,
(sz.y - 2.0*m_gldata.beginy) / sz.y,
(2.0*event.GetX() - sz.x) / sz.x,
(sz.y - 2.0*event.GetY()) / sz.y);
add_quats( spin_quat, info.quat, info.quat );
add_quats(spin_quat, m_gldata.quat, m_gldata.quat);
/* orientation has changed, redraw mesh */
Refresh(false);
}
info.beginx = event.GetX();
info.beginy = event.GetY();
m_gldata.beginx = event.GetX();
m_gldata.beginy = event.GetY();
}
void TestGLCanvas::InitGL()
@@ -255,3 +292,20 @@ void TestGLCanvas::InitGL()
glEnable(GL_COLOR_MATERIAL);
}
void TestGLCanvas::ResetProjectionMode()
{
int w, h;
GetClientSize(&w, &h);
#ifndef __WXMOTIF__
if ( GetContext() )
#endif
{
SetCurrent();
glViewport(0, 0, (GLint) w, (GLint) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)w/h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
}

View File

@@ -468,7 +468,7 @@ LINK32=link.exe
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\lw.cpp
SOURCE=.\dxfrenderer.cpp
# End Source File
# Begin Source File

Binary file not shown.

View File

@@ -17,35 +17,37 @@
#include "wx/app.h"
#include "wx/menu.h"
#include "wx/dcclient.h"
#include "wx/wfstream.h"
#if wxUSE_ZLIB
#include "wx/zstream.h"
#endif
#include "wx/glcanvas.h"
extern "C"
{
#include "lw.h"
#include "trackball.h"
}
/* information needed to display lightwave mesh */
typedef struct
#include "dxfrenderer.h"
// OpenGL view data
struct GLData
{
// gint do_init; /* true if initgl not yet called */
bool do_init;
lwObject *lwobject; /* lightwave object mesh */
float beginx,beginy; /* position of mouse */
float quat[4]; /* orientation of object */
float zoom; /* field of view in degrees */
} mesh_info;
bool initialized; // have OpenGL been initialized?
float beginx, beginy; // position of mouse
float quat[4]; // orientation of object
float zoom; // field of view in degrees
};
/* Define a new application type */
// Define a new application type
class MyApp: public wxApp
{
public:
bool OnInit();
};
/* Define a new frame type */
// Define a new frame type
class TestGLCanvas;
class MyFrame: public wxFrame
@@ -54,7 +56,9 @@ public:
MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
const wxSize& size, long style = wxDEFAULT_FRAME_STYLE);
void OnExit(wxCommandEvent& event);
void OnMenuFileOpen(wxCommandEvent& event);
void OnMenuFileExit(wxCommandEvent& event);
void OnMenuHelpAbout(wxCommandEvent& event);
#if wxUSE_GLCANVAS
void SetCanvas( TestGLCanvas *canvas ) { m_canvas = canvas; }
@@ -79,17 +83,21 @@ public:
~TestGLCanvas();
void LoadDXF(const wxString& filename);
protected:
void OnPaint(wxPaintEvent& event);
void OnSize(wxSizeEvent& event);
void OnEraseBackground(wxEraseEvent& event);
void LoadLWO( const wxString &filename);
void OnMouse( wxMouseEvent& event );
void InitGL();
mesh_info info;
bool block;
void OnMouse(wxMouseEvent& event);
private:
void InitGL();
void ResetProjectionMode();
GLData m_gldata;
DXFRenderer m_renderer;
DECLARE_EVENT_TABLE()
};

Binary file not shown.