add line primitive to egg syntax
This commit is contained in:
parent
ace3842c21
commit
3a24581e96
|
|
@ -20,9 +20,8 @@
|
|||
#include "mesherTempl.h"
|
||||
#include "builderNormalVisualizer.h"
|
||||
#include "config_builder.h"
|
||||
|
||||
#include <geom.h>
|
||||
#include <geomprimitives.h>
|
||||
#include "geom.h"
|
||||
#include "geomprimitives.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
|
@ -401,20 +400,40 @@ expand_points(const PrimType &prim, BuilderBucket &,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template <class PrimType, class OutputIterator>
|
||||
static bool
|
||||
expand_lines(const PrimType &prim, BuilderBucket &,
|
||||
expand_lines(PrimType &prim, BuilderBucket &,
|
||||
OutputIterator result) {
|
||||
// Each line segment goes in its own primitive. This breaks up the
|
||||
// linestrips already defined; we'll re-strip them later if the
|
||||
// generate-tstrips flag is enabled.
|
||||
|
||||
int num_verts = prim.get_num_verts();
|
||||
for (int i = 1; i < num_verts; i++) {
|
||||
PrimType new_prim(prim);
|
||||
new_prim.clear_vertices();
|
||||
new_prim.add_vertex(prim.get_vertex(i-1));
|
||||
new_prim.add_vertex(prim.get_vertex(i));
|
||||
*result++ = new_prim;
|
||||
// Actually, we don't have support for meshing linestrips right now,
|
||||
// so let's not break up the linestrips we're supplied with.
|
||||
/*
|
||||
if (bucket._subdivide_polys) {
|
||||
// If we're subdividing, each line segment goes in its own
|
||||
// primitive. This breaks up the linestrips already defined;
|
||||
// we'll re-strip them later if the generate-tstrips flag is
|
||||
// enabled.
|
||||
prim.set_type(BPT_line);
|
||||
|
||||
int num_verts = prim.get_num_verts();
|
||||
for (int i = 1; i < num_verts; i++) {
|
||||
PrimType new_prim(prim);
|
||||
new_prim.clear_vertices();
|
||||
new_prim.add_vertex(prim.get_vertex(i-1));
|
||||
new_prim.add_vertex(prim.get_vertex(i));
|
||||
*result++ = new_prim;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
// If we're not to subdivide the polys, then just pass them through
|
||||
// as they are. Two vertices is a BPT_line; more than that is a
|
||||
// BPT_linestrip.
|
||||
if (prim.get_num_verts() > 2) {
|
||||
prim.set_type(BPT_linestrip);
|
||||
} else {
|
||||
prim.set_type(BPT_line);
|
||||
}
|
||||
*result++ = prim;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -467,6 +486,7 @@ expand(const PrimType &prim, BuilderBucket &bucket, OutputIterator result) {
|
|||
return expand_points(new_prim, bucket, result);
|
||||
|
||||
case BPT_line:
|
||||
case BPT_linestrip:
|
||||
new_prim.remove_doubled_verts(false);
|
||||
return expand_lines(new_prim, bucket, result);
|
||||
|
||||
|
|
@ -614,6 +634,7 @@ build_geoms(InputIterator first, InputIterator last,
|
|||
|
||||
Geom *geom = NULL;
|
||||
BuilderPrimType type = (*first).get_type();
|
||||
|
||||
switch (type) {
|
||||
case BPT_poly:
|
||||
geom = new GeomPolygon;
|
||||
|
|
@ -634,6 +655,11 @@ build_geoms(InputIterator first, InputIterator last,
|
|||
geom = new GeomLine;
|
||||
break;
|
||||
|
||||
case BPT_linestrip:
|
||||
geom = new GeomLinestrip;
|
||||
want_lengths = true;
|
||||
break;
|
||||
|
||||
case BPT_point:
|
||||
geom = new GeomPoint;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -61,16 +61,12 @@
|
|||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#include <pandabase.h>
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "builderPrimTempl.h"
|
||||
#include "builderBucket.h"
|
||||
#include "builderTypes.h"
|
||||
|
||||
#include <pta_ushort.h>
|
||||
#include <geom.h>
|
||||
#include "pta_ushort.h"
|
||||
#include "geom.h"
|
||||
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEGG, EXPTP_PANDAEGG, BuilderPrimTempl<BuilderVertex>);
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDAEGG, EXPTP_PANDAEGG, BuilderPrimTempl<BuilderVertexI>);
|
||||
|
|
|
|||
|
|
@ -792,6 +792,9 @@ is_valid() const {
|
|||
return num_verts >= 1;
|
||||
|
||||
case BPT_line:
|
||||
return num_verts == 2;
|
||||
|
||||
case BPT_linestrip:
|
||||
return num_verts >= 2;
|
||||
|
||||
case BPT_tri:
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "builderTypes.h"
|
||||
#include <notify.h>
|
||||
#include "notify.h"
|
||||
|
||||
ostream &operator << (ostream &out, BuilderAttribFlags baf) {
|
||||
const char *space = "";
|
||||
|
|
@ -107,6 +107,8 @@ ostream &operator << (ostream &out, BuilderPrimType bpt) {
|
|||
return out << "quad";
|
||||
case BPT_quadstrip:
|
||||
return out << "quadstrip";
|
||||
case BPT_linestrip:
|
||||
return out << "linestrip";
|
||||
}
|
||||
nassertr(false, out);
|
||||
return out << "(**invalid**)";
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@
|
|||
#ifndef BUILDERTYPES_H
|
||||
#define BUILDERTYPES_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#include <luse.h>
|
||||
#include <pta_TexCoordf.h>
|
||||
#include <pta_Vertexf.h>
|
||||
#include <pta_Normalf.h>
|
||||
#include <pta_Colorf.h>
|
||||
#include "luse.h"
|
||||
#include "pta_TexCoordf.h"
|
||||
#include "pta_Vertexf.h"
|
||||
#include "pta_Normalf.h"
|
||||
#include "pta_Colorf.h"
|
||||
|
||||
typedef TexCoordf BuilderTC;
|
||||
typedef Vertexf BuilderV;
|
||||
|
|
@ -72,6 +72,7 @@ enum BuilderPrimType {
|
|||
BPT_trifan,
|
||||
BPT_quad,
|
||||
BPT_quadstrip,
|
||||
BPT_linestrip,
|
||||
};
|
||||
|
||||
ostream &operator << (ostream &out, BuilderPrimType bpt);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef MESHER_H
|
||||
#define MESHER_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "mesherConfig.h"
|
||||
#include "mesherFanMaker.h"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_builder.h"
|
||||
|
||||
template <class PrimType>
|
||||
INLINE MesherStrip<PrimType>::
|
||||
|
|
@ -1496,8 +1495,8 @@ remove_all_edges() {
|
|||
template <class PrimType>
|
||||
bool MesherStrip<PrimType>::
|
||||
pick_mate(const MesherStrip &a_strip, const MesherStrip &b_strip,
|
||||
const Edge &a_edge, const Edge &b_edge,
|
||||
const BuilderBucket &bucket) const {
|
||||
const Edge &a_edge, const Edge &b_edge,
|
||||
const BuilderBucket &bucket) const {
|
||||
// First, try to avoid polluting quads, quadstrips, and tristrips
|
||||
// with arbitrary triangles. When we mate a tri or tristrip to a
|
||||
// quadstrip, we end up with a tristrip that may be less versatile
|
||||
|
|
|
|||
|
|
@ -19,11 +19,12 @@
|
|||
#ifndef MESHERSTRIP_H
|
||||
#define MESHERSTRIP_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "mesherConfig.h"
|
||||
#include "builderTypes.h"
|
||||
#include "builderBucket.h"
|
||||
#include "config_builder.h"
|
||||
|
||||
#include "plist.h"
|
||||
#include <math.h>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef MESHERTEMPL_H
|
||||
#define MESHERTEMPL_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "mesherConfig.h"
|
||||
#include "builderBucket.h"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
eggExternalReference.I eggExternalReference.h \
|
||||
eggFilenameNode.I eggFilenameNode.h eggGroup.I eggGroup.h \
|
||||
eggGroupNode.I eggGroupNode.h eggGroupUniquifier.h \
|
||||
eggLine.I eggLine.h \
|
||||
eggMaterial.I eggMaterial.h eggMaterialCollection.I \
|
||||
eggMaterialCollection.h eggMiscFuncs.I eggMiscFuncs.h \
|
||||
eggMorph.I eggMorph.h eggMorphList.I eggMorphList.h \
|
||||
|
|
@ -44,7 +45,7 @@
|
|||
eggBinMaker.cxx eggComment.cxx eggCoordinateSystem.cxx \
|
||||
eggCurve.cxx eggData.cxx eggExternalReference.cxx \
|
||||
eggFilenameNode.cxx eggGroup.cxx eggGroupNode.cxx \
|
||||
eggGroupUniquifier.cxx eggMaterial.cxx \
|
||||
eggGroupUniquifier.cxx eggLine.cxx eggMaterial.cxx \
|
||||
eggMaterialCollection.cxx eggMiscFuncs.cxx eggMorphList.cxx \
|
||||
eggNamedObject.cxx eggNameUniquifier.cxx eggNode.cxx \
|
||||
eggNurbsCurve.cxx eggNurbsSurface.cxx eggObject.cxx \
|
||||
|
|
@ -67,7 +68,9 @@
|
|||
eggCurve.h eggData.I eggData.h eggExternalReference.I \
|
||||
eggExternalReference.h eggFilenameNode.I eggFilenameNode.h \
|
||||
eggGroup.I eggGroup.h eggGroupNode.I eggGroupNode.h \
|
||||
eggGroupUniquifier.h eggMaterial.I \
|
||||
eggGroupUniquifier.h \
|
||||
eggLine.I eggLine.h \
|
||||
eggMaterial.I \
|
||||
eggMaterial.h eggMaterialCollection.I eggMaterialCollection.h \
|
||||
eggMorph.I eggMorph.h eggMorphList.I eggMorphList.h \
|
||||
eggNamedObject.I eggNamedObject.h eggNameUniquifier.h eggNode.I eggNode.h \
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "eggFilenameNode.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggGroupNode.h"
|
||||
#include "eggLine.h"
|
||||
#include "eggMaterial.h"
|
||||
#include "eggNameUniquifier.h"
|
||||
#include "eggNamedObject.h"
|
||||
|
|
@ -100,6 +101,7 @@ init_libegg() {
|
|||
EggFilenameNode::init_type();
|
||||
EggGroup::init_type();
|
||||
EggGroupNode::init_type();
|
||||
EggLine::init_type();
|
||||
EggMaterial::init_type();
|
||||
EggNameUniquifier::init_type();
|
||||
EggNamedObject::init_type();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
// Filename: eggLine.I
|
||||
// Created by: drose (14Oct03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLine::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggLine::
|
||||
EggLine(const string &name) : EggPrimitive(name) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLine::Copy constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggLine::
|
||||
EggLine(const EggLine ©) : EggPrimitive(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLine::Copy assignment operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggLine &EggLine::
|
||||
operator = (const EggLine ©) {
|
||||
EggPrimitive::operator = (copy);
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Filename: eggLine.cxx
|
||||
// Created by: drose (14Oct03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eggLine.h"
|
||||
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle EggLine::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLine::write
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the point to the indicated output stream in
|
||||
// Egg format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggLine::
|
||||
write(ostream &out, int indent_level) const {
|
||||
write_header(out, indent_level, "<Line>");
|
||||
write_body(out, indent_level+2);
|
||||
indent(out, indent_level) << "}\n";
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// Filename: eggLine.h
|
||||
// Created by: drose (14Oct03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGGLINE_H
|
||||
#define EGGLINE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "eggPrimitive.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EggLine
|
||||
// Description : A line segment, or a series of connected line
|
||||
// segments, defined by a <Line> entry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEGG EggLine : public EggPrimitive {
|
||||
PUBLISHED:
|
||||
INLINE EggLine(const string &name = "");
|
||||
INLINE EggLine(const EggLine ©);
|
||||
INLINE EggLine &operator = (const EggLine ©);
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
public:
|
||||
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
EggPrimitive::init_type();
|
||||
register_type(_type_handle, "EggLine",
|
||||
EggPrimitive::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
};
|
||||
|
||||
#include "eggLine.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -17,7 +17,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPoint::Constructor
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -18,9 +18,7 @@
|
|||
|
||||
#include "eggPoint.h"
|
||||
|
||||
#include <indent.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle EggPoint::_type_handle;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "eggGroup.cxx"
|
||||
#include "eggGroupNode.cxx"
|
||||
#include "eggGroupUniquifier.cxx"
|
||||
#include "eggLine.cxx"
|
||||
#include "eggMaterial.cxx"
|
||||
#include "eggMaterialCollection.cxx"
|
||||
#include "eggMiscFuncs.cxx"
|
||||
|
|
@ -21,4 +22,3 @@
|
|||
#include "eggNode.cxx"
|
||||
#include "eggNurbsCurve.cxx"
|
||||
#include "eggNurbsSurface.cxx"
|
||||
|
||||
|
|
|
|||
|
|
@ -451,6 +451,10 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
accept();
|
||||
return INSTANCE;
|
||||
}
|
||||
"<LINE>" {
|
||||
accept();
|
||||
return LINE;
|
||||
}
|
||||
"<LOOP>" {
|
||||
accept();
|
||||
return LOOP;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "eggVertexPool.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggPoint.h"
|
||||
#include "eggLine.h"
|
||||
#include "eggNurbsSurface.h"
|
||||
#include "eggNurbsCurve.h"
|
||||
#include "eggTable.h"
|
||||
|
|
@ -121,7 +122,7 @@ egg_cleanup_parser() {
|
|||
%token DYNAMICVERTEXPOOL EXTERNAL_FILE
|
||||
%token FLIGHT GROUP HIP INTANGENT
|
||||
%token JOINT KNOTS INCLUDE
|
||||
%token INSTANCE LOOP MATERIAL MATRIX3 MATRIX4 MODEL MREF NORMAL
|
||||
%token INSTANCE LINE LOOP MATERIAL MATRIX3 MATRIX4 MODEL MREF NORMAL
|
||||
%token NURBSCURVE NURBSSURFACE OBJECTTYPE ORDER
|
||||
%token OUTTANGENT POINTLIGHT POLYGON REF RGBA ROTATE ROTX ROTY ROTZ
|
||||
%token SANIM SCALAR SCALE SEQUENCE SHADING SWITCH SWITCHCONDITION
|
||||
|
|
@ -146,8 +147,9 @@ egg_cleanup_parser() {
|
|||
%type <_egg> external_reference
|
||||
%type <_egg> vertex_pool
|
||||
%type <_egg> group
|
||||
%type <_egg> joint
|
||||
%type <_egg> instance
|
||||
%type <_egg> joint
|
||||
%type <_egg> line
|
||||
%type <_egg> polygon
|
||||
%type <_egg> point_light
|
||||
%type <_egg> nurbs_surface
|
||||
|
|
@ -218,6 +220,7 @@ node:
|
|||
| instance
|
||||
| polygon
|
||||
| point_light
|
||||
| line
|
||||
| nurbs_surface
|
||||
| nurbs_curve
|
||||
| table
|
||||
|
|
@ -1357,6 +1360,25 @@ point_light:
|
|||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* line
|
||||
*
|
||||
* enter:
|
||||
* exit: returns a new EggLine.
|
||||
*
|
||||
*/
|
||||
line:
|
||||
LINE optional_name
|
||||
{
|
||||
egg_stack.push_back(new EggLine($2));
|
||||
}
|
||||
'{' primitive_body '}'
|
||||
{
|
||||
$$ = egg_stack.back();
|
||||
egg_stack.pop_back();
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* nurbs_surface
|
||||
*
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "string_utils.h"
|
||||
#include "eggPrimitive.h"
|
||||
#include "eggPoint.h"
|
||||
#include "eggLine.h"
|
||||
#include "eggTextureCollection.h"
|
||||
#include "eggNurbsCurve.h"
|
||||
#include "eggNurbsSurface.h"
|
||||
|
|
@ -253,10 +254,12 @@ make_nonindexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
|
|||
make_nurbs_surface(DCAST(EggNurbsSurface, egg_prim), parent, mat);
|
||||
|
||||
} else {
|
||||
// A normal primitive: polygon or point.
|
||||
// A normal primitive: polygon, line, or point.
|
||||
BuilderPrim bprim;
|
||||
bprim.set_type(BPT_poly);
|
||||
if (egg_prim->is_of_type(EggPoint::get_class_type())) {
|
||||
if (egg_prim->is_of_type(EggLine::get_class_type())) {
|
||||
bprim.set_type(BPT_linestrip);
|
||||
} else if (egg_prim->is_of_type(EggPoint::get_class_type())) {
|
||||
bprim.set_type(BPT_point);
|
||||
}
|
||||
|
||||
|
|
@ -344,7 +347,9 @@ make_indexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
|
|||
|
||||
BuilderPrimI bprim;
|
||||
bprim.set_type(BPT_poly);
|
||||
if (egg_prim->is_of_type(EggPoint::get_class_type())) {
|
||||
if (egg_prim->is_of_type(EggLine::get_class_type())) {
|
||||
bprim.set_type(BPT_linestrip);
|
||||
} else if (egg_prim->is_of_type(EggPoint::get_class_type())) {
|
||||
bprim.set_type(BPT_point);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue