*** empty log message ***
This commit is contained in:
parent
9e1e9f09f6
commit
28b5f9e924
|
|
@ -62,6 +62,12 @@ run() {
|
|||
}
|
||||
|
||||
LwoHeader *header = DCAST(LwoHeader, chunk);
|
||||
if (!header->is_valid()) {
|
||||
nout << "File " << _input_filename
|
||||
<< " is not recognized as a Lightwave Object file. "
|
||||
<< "Perhaps the version is too recent.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_data.set_coordinate_system(_coordinate_system);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
lwoClip.cxx lwoClip.h \
|
||||
lwoDiscontinuousVertexMap.cxx lwoDiscontinuousVertexMap.h \
|
||||
lwoGroupChunk.cxx lwoGroupChunk.h \
|
||||
lwoHeader.cxx \
|
||||
lwoHeader.h lwoInputFile.cxx lwoInputFile.h \
|
||||
lwoHeader.I lwoHeader.cxx lwoHeader.h \
|
||||
lwoInputFile.I lwoInputFile.cxx lwoInputFile.h \
|
||||
lwoLayer.h lwoLayer.cxx \
|
||||
lwoPoints.h lwoPoints.cxx \
|
||||
lwoPolygons.h lwoPolygons.cxx \
|
||||
|
|
@ -53,8 +53,8 @@
|
|||
lwoClip.h \
|
||||
lwoDiscontinuousVertexMap.h \
|
||||
lwoGroupChunk.h \
|
||||
lwoHeader.h \
|
||||
lwoInputFile.h \
|
||||
lwoHeader.I lwoHeader.h \
|
||||
lwoInputFile.I lwoInputFile.h \
|
||||
lwoLayer.h \
|
||||
lwoPoints.h \
|
||||
lwoPolygons.h \
|
||||
|
|
|
|||
|
|
@ -4,3 +4,32 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "iffId.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: IffId::output
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void IffId::
|
||||
output(ostream &out) const {
|
||||
// If all of the characters are printable, just output them.
|
||||
if (isprint(_id._c[0]) && isprint(_id._c[1]) &&
|
||||
isprint(_id._c[2]) && isprint(_id._c[3])) {
|
||||
out << _id._c[0] << _id._c[1] << _id._c[2] << _id._c[3];
|
||||
|
||||
} else if (isprint(_id._c[0]) && isprint(_id._c[1]) &&
|
||||
isprint(_id._c[2]) && _id._c[3] == '\0') {
|
||||
// If the last character is 0, output a 3-letter ID.
|
||||
out << _id._c[0] << _id._c[1] << _id._c[2];
|
||||
|
||||
} else {
|
||||
// Otherwise, write out the hex.
|
||||
out << "0x" << hex << setfill('0');
|
||||
for (int i = 0; i < 4; i++) {
|
||||
out << setw(2) << (int)(unsigned char)_id._c[i];
|
||||
}
|
||||
out << dec << setfill(' ');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ public:
|
|||
INLINE bool operator < (const IffId &other) const;
|
||||
|
||||
INLINE string get_name() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
union {
|
||||
|
|
@ -40,7 +42,8 @@ private:
|
|||
#include "iffId.I"
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const IffId &id) {
|
||||
return out << id.get_name();
|
||||
id.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ IffInputFile() {
|
|||
_input = (istream *)NULL;
|
||||
_owns_istream = false;
|
||||
_eof = true;
|
||||
_unexpected_eof = false;
|
||||
_bytes_read = 0;
|
||||
}
|
||||
|
||||
|
|
@ -70,6 +71,7 @@ set_input(istream *input, bool owns_istream) {
|
|||
_input = input;
|
||||
_owns_istream = owns_istream;
|
||||
_eof = false;
|
||||
_unexpected_eof = false;
|
||||
_bytes_read = 0;
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +243,10 @@ get_chunk() {
|
|||
|
||||
if (chunk->read_iff(this, end_point)) {
|
||||
if (is_eof()) {
|
||||
nout << "Unexpected EOF on file.\n";
|
||||
if (!_unexpected_eof) {
|
||||
nout << "Unexpected EOF on file reading " << *chunk << "\n";
|
||||
_unexpected_eof = true;
|
||||
}
|
||||
return (IffChunk *)NULL;
|
||||
}
|
||||
|
||||
|
|
@ -292,7 +297,10 @@ get_subchunk(IffChunk *context) {
|
|||
|
||||
if (chunk->read_iff(this, end_point)) {
|
||||
if (is_eof()) {
|
||||
nout << "Unexpected EOF on file.\n";
|
||||
if (!_unexpected_eof) {
|
||||
nout << "Unexpected EOF on file reading " << *chunk << "\n";
|
||||
_unexpected_eof = true;
|
||||
}
|
||||
return (IffChunk *)NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ protected:
|
|||
Filename _filename;
|
||||
bool _owns_istream;
|
||||
bool _eof;
|
||||
bool _unexpected_eof;
|
||||
size_t _bytes_read;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// Filename: lwoHeader.I
|
||||
// Created by: drose (24Apr01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LwoHeader::is_valid
|
||||
// Access: Public
|
||||
// Description: Returns true if the header represents a valid and
|
||||
// recognized Lightwave header, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool LwoHeader::
|
||||
is_valid() const {
|
||||
return _valid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LwoHeader::get_version
|
||||
// Access: Public
|
||||
// Description: Returns the version of the Lightwave file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double LwoHeader::
|
||||
get_version() const {
|
||||
return _version;
|
||||
}
|
||||
|
||||
|
|
@ -4,12 +4,23 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lwoHeader.h"
|
||||
#include "iffInputFile.h"
|
||||
#include "lwoInputFile.h"
|
||||
|
||||
#include <indent.h>
|
||||
|
||||
TypeHandle LwoHeader::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LwoHeader::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LwoHeader::
|
||||
LwoHeader() {
|
||||
_valid = false;
|
||||
_version = 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LwoHeader::read_iff
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -22,8 +33,24 @@ TypeHandle LwoHeader::_type_handle;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool LwoHeader::
|
||||
read_iff(IffInputFile *in, size_t stop_at) {
|
||||
_lwid = in->get_id();
|
||||
read_chunks_iff(in, stop_at);
|
||||
LwoInputFile *lin = DCAST(LwoInputFile, in);
|
||||
|
||||
_lwid = lin->get_id();
|
||||
|
||||
if (_lwid == IffId("LWO2")) {
|
||||
_valid = true;
|
||||
_version = 6.0;
|
||||
} else if (_lwid == IffId("LWOB")) {
|
||||
_valid = true;
|
||||
_version = 5.0;
|
||||
}
|
||||
|
||||
if (_valid) {
|
||||
lin->set_lwo_version(_version);
|
||||
}
|
||||
|
||||
read_chunks_iff(lin, stop_at);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,20 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class LwoHeader : public LwoGroupChunk {
|
||||
public:
|
||||
LwoHeader();
|
||||
|
||||
IffId _lwid;
|
||||
|
||||
INLINE bool is_valid() const;
|
||||
INLINE double get_version() const;
|
||||
|
||||
public:
|
||||
virtual bool read_iff(IffInputFile *in, size_t stop_at);
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
bool _valid;
|
||||
double _version;
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
|
|
@ -40,6 +49,8 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "lwoHeader.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
// Filename: lwoInputFile.I
|
||||
// Created by: drose (24Apr01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LwoInputFile::get_lwo_version
|
||||
// Access: Public
|
||||
// Description: Returns the version of the Lightwave file being read.
|
||||
// This is unknown until the header record has been
|
||||
// read; then it will be set by the header.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double LwoInputFile::
|
||||
get_lwo_version() const {
|
||||
return _lwo_version;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LwoInputFile::set_lwo_version
|
||||
// Access: Public
|
||||
// Description: Changes the version number reported for the Lightwave
|
||||
// file. Normally this is only called by LwoHeader as
|
||||
// it is read.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LwoInputFile::
|
||||
set_lwo_version(double lwo_version) {
|
||||
_lwo_version = lwo_version;
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +120,8 @@ make_new_chunk(IffId id) {
|
|||
} else if (id == IffId("POLS")) {
|
||||
return new LwoPolygons;
|
||||
|
||||
} else if (id == IffId("TAGS")) {
|
||||
} else if (id == IffId("TAGS") ||
|
||||
id == IffId("SRFS")) {
|
||||
return new LwoTags;
|
||||
|
||||
} else if (id == IffId("PTAG")) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ public:
|
|||
LwoInputFile();
|
||||
~LwoInputFile();
|
||||
|
||||
INLINE double get_lwo_version() const;
|
||||
INLINE void set_lwo_version(double version);
|
||||
|
||||
int get_vx();
|
||||
LVecBase3f get_vec3();
|
||||
Filename get_filename();
|
||||
|
|
@ -29,6 +32,9 @@ public:
|
|||
protected:
|
||||
virtual IffChunk *make_new_chunk(IffId id);
|
||||
|
||||
private:
|
||||
double _lwo_version;
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
@ -47,6 +53,8 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "lwoInputFile.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,23 +45,68 @@ bool LwoPolygons::
|
|||
read_iff(IffInputFile *in, size_t stop_at) {
|
||||
LwoInputFile *lin = DCAST(LwoInputFile, in);
|
||||
|
||||
_polygon_type = lin->get_id();
|
||||
if (lin->get_lwo_version() >= 6.0) {
|
||||
// 6.x style syntax:
|
||||
// POLS { type[ID4], ( numvert+flags[U2], vert[VX] # numvert )* }
|
||||
|
||||
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
|
||||
int nf = lin->get_be_int16();
|
||||
int num_vertices = nf & PF_numverts_mask;
|
||||
_polygon_type = lin->get_id();
|
||||
|
||||
PT(Polygon) poly = new Polygon;
|
||||
poly->_flags = nf & ~PF_numverts_mask;
|
||||
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
poly->_vertices.push_back(lin->get_vx());
|
||||
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
|
||||
int nf = lin->get_be_uint16();
|
||||
int num_vertices = nf & PF_numverts_mask;
|
||||
|
||||
PT(Polygon) poly = new Polygon;
|
||||
poly->_flags = nf & ~PF_numverts_mask;
|
||||
poly->_surface_index = -1;
|
||||
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
int vindex = lin->get_vx();
|
||||
poly->_vertices.push_back(vindex);
|
||||
}
|
||||
|
||||
_polygons.push_back(poly);
|
||||
}
|
||||
|
||||
_polygons.push_back(poly);
|
||||
} else {
|
||||
// 5.x style syntax:
|
||||
// POLS { ( numvert[U2], vert[VX] # numvert, +/-(surf+1)[I2], numdetail[U2]? )* }
|
||||
_polygon_type = IffId("FACE");
|
||||
|
||||
int num_decals = 0;
|
||||
while (lin->get_bytes_read() < stop_at && !lin->is_eof()) {
|
||||
int num_vertices = lin->get_be_uint16();
|
||||
|
||||
PT(Polygon) poly = new Polygon;
|
||||
poly->_flags = 0;
|
||||
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
int vindex = lin->get_vx();
|
||||
poly->_vertices.push_back(vindex);
|
||||
}
|
||||
|
||||
int surface = lin->get_be_int16();
|
||||
|
||||
if (num_decals > 0) {
|
||||
// This is a decal polygon of a previous polygon.
|
||||
num_decals--;
|
||||
poly->_flags |= PF_decal;
|
||||
|
||||
} else {
|
||||
if (surface < 0) {
|
||||
num_decals = lin->get_be_int16();
|
||||
surface = -surface;
|
||||
}
|
||||
}
|
||||
|
||||
// The surface index is stored +1 to allow signedness to be
|
||||
// examined.
|
||||
poly->_surface_index = surface - 1;
|
||||
|
||||
_polygons.push_back(poly);
|
||||
}
|
||||
}
|
||||
|
||||
return (lin->get_bytes_read() == stop_at);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -25,13 +25,24 @@ public:
|
|||
enum PolygonFlags {
|
||||
PF_continuity_1 = 0x0400,
|
||||
PF_continuity_2 = 0x0800,
|
||||
PF_numverts_mask = 0x03ff
|
||||
PF_numverts_mask = 0x03ff,
|
||||
|
||||
// This "flag" is stored artificially when reading 5.x LWOB files,
|
||||
// and indicates that the polygon is a decal of a preceding
|
||||
// polygon.
|
||||
PF_decal = 0x0001
|
||||
};
|
||||
|
||||
class Polygon : public ReferenceCount {
|
||||
public:
|
||||
int _flags;
|
||||
vector_int _vertices;
|
||||
|
||||
// This value is only filled in when reading 5.x LWOB files, and
|
||||
// indicates the surface index of the polygon within a preceding
|
||||
// SRFS (LwoTags) chunk. For 6.x and later files, this will be
|
||||
// set to -1.
|
||||
int _surface_index;
|
||||
};
|
||||
|
||||
int get_num_polygons() const;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@
|
|||
// Class : LwoTags
|
||||
// Description : An array of tag strings that will be referenced by
|
||||
// later chunks.
|
||||
//
|
||||
// This also serves as an array of surface names to be
|
||||
// referenced by a later LwoPolygons chunk, in 5.x LWOB
|
||||
// files. The chunk id can be used to differentiate the
|
||||
// meaning (TAGS vs. SRFS).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class LwoTags : public LwoChunk {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -7,8 +7,26 @@
|
|||
#include "lwoToEggConverter.h"
|
||||
#include "cLwoLayer.h"
|
||||
|
||||
#include <lwoVertexMap.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLwoPoints::add_vmap
|
||||
// Access: Public
|
||||
// Description: Associated the indicated VertexMap with the points
|
||||
// set. This may define such niceties as UV coordinates
|
||||
// or per-vertex color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLwoPoints::
|
||||
add_vmap(const LwoVertexMap *lwo_vmap) {
|
||||
VMapNames &names = _vmap[lwo_vmap->_map_type];
|
||||
bool inserted = names.insert(VMapNames::value_type(lwo_vmap->_name, lwo_vmap)).second;
|
||||
if (!inserted) {
|
||||
nout << "Multiple vertex maps on the same points of type "
|
||||
<< lwo_vmap->_map_type << " named " << lwo_vmap->_name << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLwoPoints::make_egg
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -12,7 +12,10 @@
|
|||
#include <eggVertexPool.h>
|
||||
#include <pointerTo.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
class LwoToEggConverter;
|
||||
class LwoVertexMap;
|
||||
class CLwoLayer;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -26,6 +29,8 @@ public:
|
|||
INLINE CLwoPoints(LwoToEggConverter *converter, const LwoPoints *points,
|
||||
CLwoLayer *layer);
|
||||
|
||||
void add_vmap(const LwoVertexMap *lwo_vmap);
|
||||
|
||||
void make_egg();
|
||||
void connect_egg();
|
||||
|
||||
|
|
@ -33,6 +38,12 @@ public:
|
|||
CPT(LwoPoints) _points;
|
||||
CLwoLayer *_layer;
|
||||
PT(EggVertexPool) _egg_vpool;
|
||||
|
||||
// A number of vertex maps may be associated, by type and then by
|
||||
// name.
|
||||
typedef map<string, const LwoVertexMap *> VMapNames;
|
||||
typedef map<IffId, VMapNames> VmapTypes;
|
||||
VmapTypes _vmap;
|
||||
};
|
||||
|
||||
#include "cLwoPoints.I"
|
||||
|
|
|
|||
|
|
@ -38,8 +38,9 @@ make_egg() {
|
|||
make_faces();
|
||||
|
||||
} else {
|
||||
nout << "Ignoring unknown geometry type " << _polygons->_polygon_type
|
||||
<< "\n";
|
||||
nout << "Unknown geometry type " << _polygons->_polygon_type
|
||||
<< "; treating as FACE.\n";
|
||||
make_faces();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +51,8 @@ make_egg() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLwoPolygons::
|
||||
connect_egg() {
|
||||
nassertv(_points->_layer->_egg_group != (EggGroup *)NULL);
|
||||
nassertv(_egg_group != (EggGroup *)NULL);
|
||||
_points->_layer->_egg_group->steal_children(*_egg_group);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <lwoLayer.h>
|
||||
#include <lwoPoints.h>
|
||||
#include <lwoPolygons.h>
|
||||
#include <lwoVertexMap.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -98,6 +99,7 @@ void LwoToEggConverter::
|
|||
collect_lwo() {
|
||||
CLwoLayer *last_layer = (CLwoLayer *)NULL;
|
||||
CLwoPoints *last_points = (CLwoPoints *)NULL;
|
||||
CLwoPolygons *last_polygons = (CLwoPolygons *)NULL;
|
||||
|
||||
int num_chunks = _lwo_header->get_num_chunks();
|
||||
for (int i = 0; i < num_chunks; i++) {
|
||||
|
|
@ -115,6 +117,7 @@ collect_lwo() {
|
|||
_layers[number] = layer;
|
||||
last_layer = layer;
|
||||
last_points = (CLwoPoints *)NULL;
|
||||
last_polygons = (CLwoPolygons *)NULL;
|
||||
|
||||
} else if (chunk->is_of_type(LwoPoints::get_class_type())) {
|
||||
if (last_layer == (CLwoLayer *)NULL) {
|
||||
|
|
@ -126,6 +129,14 @@ collect_lwo() {
|
|||
_points.push_back(points);
|
||||
last_points = points;
|
||||
|
||||
} else if (chunk->is_of_type(LwoVertexMap::get_class_type())) {
|
||||
if (last_points == (CLwoPoints *)NULL) {
|
||||
nout << "Vertex map chunk encountered without a preceding points chunk.\n";
|
||||
} else {
|
||||
const LwoVertexMap *lwo_vmap = DCAST(LwoVertexMap, chunk);
|
||||
last_points->add_vmap(lwo_vmap);
|
||||
}
|
||||
|
||||
} else if (chunk->is_of_type(LwoPolygons::get_class_type())) {
|
||||
if (last_points == (CLwoPoints *)NULL) {
|
||||
nout << "Polygon chunk encountered without a preceding points chunk.\n";
|
||||
|
|
@ -133,6 +144,7 @@ collect_lwo() {
|
|||
const LwoPolygons *lwo_polygons = DCAST(LwoPolygons, chunk);
|
||||
CLwoPolygons *polygons = new CLwoPolygons(this, lwo_polygons, last_points);
|
||||
_polygons.push_back(polygons);
|
||||
last_polygons = polygons;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -146,6 +158,10 @@ collect_lwo() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void LwoToEggConverter::
|
||||
make_egg() {
|
||||
if (_generic_layer != (CLwoLayer *)NULL) {
|
||||
_generic_layer->make_egg();
|
||||
}
|
||||
|
||||
Layers::iterator li;
|
||||
for (li = _layers.begin(); li != _layers.end(); ++li) {
|
||||
CLwoLayer *layer = (*li);
|
||||
|
|
@ -174,6 +190,10 @@ make_egg() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void LwoToEggConverter::
|
||||
connect_egg() {
|
||||
if (_generic_layer != (CLwoLayer *)NULL) {
|
||||
_generic_layer->connect_egg();
|
||||
}
|
||||
|
||||
Layers::iterator li;
|
||||
for (li = _layers.begin(); li != _layers.end(); ++li) {
|
||||
CLwoLayer *layer = (*li);
|
||||
|
|
|
|||
Loading…
Reference in New Issue