607 lines
16 KiB
C
607 lines
16 KiB
C
|
// Copyright (c) 1997,1998,1999,2000,2001
|
||
|
// Utrecht University (The Netherlands),
|
||
|
// ETH Zurich (Switzerland),
|
||
|
// INRIA Sophia-Antipolis (France),
|
||
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||
|
//
|
||
|
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||
|
// modify it under the terms of the GNU Lesser General Public License as
|
||
|
// published by the Free Software Foundation; either version 3 of the License,
|
||
|
// or (at your option) any later version.
|
||
|
//
|
||
|
// Licensees holding a valid commercial license may use this file in
|
||
|
// accordance with the commercial license agreement provided with the software.
|
||
|
//
|
||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
//
|
||
|
// $URL$
|
||
|
// $Id$
|
||
|
// SPDX-License-Identifier: LGPL-3.0+
|
||
|
//
|
||
|
//
|
||
|
// Author(s) : Andreas Fabri, Sylvain Pion
|
||
|
|
||
|
#ifndef CGAL_GEOMVIEW_STREAM_H
|
||
|
#define CGAL_GEOMVIEW_STREAM_H
|
||
|
|
||
|
#include <CGAL/basic.h>
|
||
|
|
||
|
#ifdef CGAL_USE_GEOMVIEW
|
||
|
|
||
|
#include <CGAL/Bbox_2.h>
|
||
|
#include <CGAL/Bbox_3.h>
|
||
|
#include <CGAL/IO/Color.h>
|
||
|
#include <CGAL/IO/Ostream_iterator.h>
|
||
|
|
||
|
#include <CGAL/export/CGAL.h>
|
||
|
|
||
|
#include <map>
|
||
|
#include <vector>
|
||
|
#include <utility>
|
||
|
#include <string>
|
||
|
#include <iterator>
|
||
|
#include <algorithm>
|
||
|
|
||
|
namespace CGAL {
|
||
|
|
||
|
class CGAL_EXPORT Geomview_stream {
|
||
|
public:
|
||
|
Geomview_stream(const Bbox_3 &bbox = Bbox_3(0,0,0, 1,1,1),
|
||
|
const char *machine = NULL,
|
||
|
const char *login = NULL);
|
||
|
|
||
|
~Geomview_stream();
|
||
|
|
||
|
Geomview_stream &operator<<(const Color &c);
|
||
|
Geomview_stream &operator<<(const std::string & s);
|
||
|
Geomview_stream &operator<<(int i);
|
||
|
Geomview_stream &operator<<(unsigned int i);
|
||
|
Geomview_stream &operator<<(long i);
|
||
|
Geomview_stream &operator<<(unsigned long i);
|
||
|
Geomview_stream &operator<<(double d);
|
||
|
|
||
|
template < class InputIterator >
|
||
|
void
|
||
|
draw_triangles(InputIterator begin, InputIterator end);
|
||
|
|
||
|
Geomview_stream &operator>>(char *expr);
|
||
|
|
||
|
void clear();
|
||
|
void look_recenter();
|
||
|
|
||
|
void set_bg_color(const Color &c);
|
||
|
|
||
|
Color get_vertex_color() const;
|
||
|
Color get_edge_color() const;
|
||
|
Color get_face_color() const;
|
||
|
|
||
|
Color set_vertex_color(const Color&);
|
||
|
Color set_edge_color(const Color&);
|
||
|
Color set_face_color(const Color&);
|
||
|
|
||
|
double vcr() const;
|
||
|
double vcg() const;
|
||
|
double vcb() const;
|
||
|
|
||
|
double ecr() const;
|
||
|
double ecg() const;
|
||
|
double ecb() const;
|
||
|
|
||
|
double fcr() const;
|
||
|
double fcg() const;
|
||
|
double fcb() const;
|
||
|
|
||
|
double get_vertex_radius() const
|
||
|
{
|
||
|
return radius;
|
||
|
}
|
||
|
double set_vertex_radius(double r)
|
||
|
{
|
||
|
std::swap(r, radius);
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
int get_line_width() const
|
||
|
{
|
||
|
return line_width;
|
||
|
}
|
||
|
int set_line_width(int w)
|
||
|
{
|
||
|
std::swap(w, line_width);
|
||
|
return w;
|
||
|
}
|
||
|
|
||
|
bool set_wired(bool b)
|
||
|
{
|
||
|
std::swap(b, wired_flag);
|
||
|
return b;
|
||
|
}
|
||
|
bool get_wired() const
|
||
|
{
|
||
|
return wired_flag;
|
||
|
}
|
||
|
|
||
|
bool set_echo(bool b)
|
||
|
{
|
||
|
std::swap(b, echo_flag);
|
||
|
return b;
|
||
|
}
|
||
|
bool get_echo() const
|
||
|
{
|
||
|
return echo_flag;
|
||
|
}
|
||
|
|
||
|
bool set_raw(bool b)
|
||
|
{
|
||
|
std::swap(b, raw_flag);
|
||
|
return b;
|
||
|
}
|
||
|
bool get_raw() const
|
||
|
{
|
||
|
return raw_flag;
|
||
|
}
|
||
|
|
||
|
bool set_trace(bool b)
|
||
|
{
|
||
|
std::swap(b, trace_flag);
|
||
|
return b;
|
||
|
}
|
||
|
bool get_trace() const
|
||
|
{
|
||
|
return trace_flag;
|
||
|
}
|
||
|
|
||
|
void trace(const std::string s) const
|
||
|
{
|
||
|
if (get_trace())
|
||
|
std::cerr << s;
|
||
|
}
|
||
|
void trace(double d) const
|
||
|
{
|
||
|
if (get_trace())
|
||
|
std::cerr << d << ' ';
|
||
|
}
|
||
|
void trace(int i) const
|
||
|
{
|
||
|
if (get_trace())
|
||
|
std::cerr << i << ' ';
|
||
|
}
|
||
|
void trace(unsigned int i) const
|
||
|
{
|
||
|
if (get_trace())
|
||
|
std::cerr << i << ' ';
|
||
|
}
|
||
|
|
||
|
bool set_binary_mode(bool b = true)
|
||
|
{
|
||
|
std::swap(b, binary_flag);
|
||
|
return b;
|
||
|
}
|
||
|
bool set_ascii_mode(bool b = true)
|
||
|
{
|
||
|
return !set_binary_mode(!b);
|
||
|
}
|
||
|
bool get_binary_mode() const
|
||
|
{
|
||
|
return binary_flag;
|
||
|
}
|
||
|
bool get_ascii_mode() const
|
||
|
{
|
||
|
return !binary_flag;
|
||
|
}
|
||
|
|
||
|
std::string get_new_id(const std::string & s);
|
||
|
|
||
|
const Bbox_3 & get_bbox()
|
||
|
{
|
||
|
return bb;
|
||
|
}
|
||
|
|
||
|
void pickplane()
|
||
|
{
|
||
|
pickplane(get_bbox());
|
||
|
}
|
||
|
|
||
|
static char* nth(char* s, int count);
|
||
|
static void parse_point(const char* pickpoint,
|
||
|
double &x, double &y, double &z, double &w);
|
||
|
private:
|
||
|
void setup_geomview(const char *machine, const char *login);
|
||
|
void frame(const Bbox_3 &bbox);
|
||
|
void pickplane(const Bbox_3 &bbox);
|
||
|
|
||
|
Bbox_3 bb;
|
||
|
Color vertex_color, edge_color, face_color;
|
||
|
bool wired_flag; // decides if we draw surfaces or edges.
|
||
|
bool echo_flag; // decides if we echo the point we get back to Geomview.
|
||
|
bool raw_flag; // decides if we output footers and headers.
|
||
|
bool trace_flag; // makes operator<<() write a trace on cerr.
|
||
|
bool binary_flag; // makes operator<<() write binary format
|
||
|
int line_width; // width of edges
|
||
|
double radius; // radius of vertices
|
||
|
int in, out; // file descriptors for input and output pipes
|
||
|
int pid; // the geomview process identification
|
||
|
std::map<std::string, int> id; // used to get a unique ID per type.
|
||
|
};
|
||
|
|
||
|
// Factorize code for Point_2 and Point_3.
|
||
|
template < class FT >
|
||
|
void
|
||
|
output_point(Geomview_stream &gv, const FT &x, const FT &y, const FT &z)
|
||
|
{
|
||
|
bool ascii_bak = true; // the initialization value shuts up the compiler.
|
||
|
if (!gv.get_raw()) {
|
||
|
ascii_bak = gv.set_ascii_mode();
|
||
|
gv << "(geometry " << gv.get_new_id("P")
|
||
|
<< " {appearance {linewidth 5 material {edgecolor "
|
||
|
<< gv.vcr() << gv.vcg() << gv.vcb() << "}}{SKEL 1 1 ";
|
||
|
}
|
||
|
|
||
|
gv << CGAL::to_double(x) << CGAL::to_double(y) << CGAL::to_double(z);
|
||
|
|
||
|
if (!gv.get_raw()) {
|
||
|
gv << "1 0\n}})";
|
||
|
gv.set_ascii_mode(ascii_bak);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if defined CGAL_POINT_2_H && \
|
||
|
!defined CGAL_GV_OUT_POINT_2_H
|
||
|
#define CGAL_GV_OUT_POINT_2_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Point_2<R> &p)
|
||
|
{
|
||
|
typename R::FT zero(0);
|
||
|
output_point(gv, p.x(), p.y(), zero);
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined CGAL_POINT_3_H && \
|
||
|
!defined CGAL_GV_OUT_POINT_3_H
|
||
|
#define CGAL_GV_OUT_POINT_3_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Point_3<R> &p)
|
||
|
{
|
||
|
output_point(gv, p.x(), p.y(), p.z());
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// The following code is the same for Segment_2 and Segment_3.
|
||
|
template < class Segment >
|
||
|
void
|
||
|
output_segment(Geomview_stream &gv, const Segment &segment)
|
||
|
{
|
||
|
bool ascii_bak = gv.set_ascii_mode();
|
||
|
gv << "(geometry " << gv.get_new_id("Seg")
|
||
|
<< " {appearance {linewidth "
|
||
|
<< gv.get_line_width() << "}{VECT "
|
||
|
<< 1 << 2 << 1 // 1 polyline, two vertices, 1 color
|
||
|
<< 2 // the first polyline contains 2 vertices
|
||
|
<< 1; // and it has 1 color
|
||
|
|
||
|
// here are start and end points
|
||
|
bool raw_bak = gv.set_raw(true);
|
||
|
gv << segment.source() << segment.target();
|
||
|
gv.set_raw(raw_bak);
|
||
|
|
||
|
// and the color of the segment and its opaqueness
|
||
|
gv << gv.ecr() << gv.ecg() << gv.ecb() << 1.0 << "}})";
|
||
|
gv.set_ascii_mode(ascii_bak);
|
||
|
}
|
||
|
|
||
|
#if defined CGAL_SEGMENT_2_H && \
|
||
|
!defined CGAL_GV_OUT_SEGMENT_2_H
|
||
|
#define CGAL_GV_OUT_SEGMENT_2_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Segment_2<R> &segment)
|
||
|
{
|
||
|
output_segment(gv, segment);
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined CGAL_SEGMENT_3_H && \
|
||
|
!defined CGAL_GV_OUT_SEGMENT_3_H
|
||
|
#define CGAL_GV_OUT_SEGMENT_3_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Segment_3<R> &segment)
|
||
|
{
|
||
|
output_segment(gv, segment);
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// The following code is the same for Triangle_2 and Triangle_3.
|
||
|
template < class Triangle >
|
||
|
void
|
||
|
output_triangle(Geomview_stream &gv, const Triangle &triangle)
|
||
|
{
|
||
|
bool ascii_bak = gv.set_ascii_mode();
|
||
|
gv << "(geometry " << gv.get_new_id("Tr")
|
||
|
<< " {appearance {+edge material {edgecolor "
|
||
|
<< gv.ecr() << gv.ecg() << gv.ecb() << " } shading constant}{ ";
|
||
|
gv.set_binary_mode();
|
||
|
// it's a planar polygon
|
||
|
gv << "OFF BINARY\n"
|
||
|
|
||
|
// it has 3 vertices, 1 face and 3 edges
|
||
|
<< 3 << 1 << 3;
|
||
|
|
||
|
bool raw_bak = gv.set_raw(true);
|
||
|
for(int i=0; i<3; i++)
|
||
|
gv << triangle[i];
|
||
|
gv.set_raw(raw_bak);
|
||
|
|
||
|
// the face
|
||
|
gv << 3 << 0 << 1 << 2 << 4 << gv.fcr() << gv.fcg() << gv.fcb() << 1.0
|
||
|
<< "}})";
|
||
|
gv.set_ascii_mode(ascii_bak);
|
||
|
}
|
||
|
|
||
|
// Draws a set of triangles as OFF format (it's faster than one by one).
|
||
|
template < class InputIterator >
|
||
|
void
|
||
|
Geomview_stream::draw_triangles(InputIterator begin, InputIterator end)
|
||
|
{
|
||
|
typedef typename std::iterator_traits<InputIterator>::value_type Triangle;
|
||
|
typedef typename Kernel_traits<Triangle>::Kernel Kernel;
|
||
|
typedef typename Kernel::Point_3 Point;
|
||
|
typedef typename Kernel::Less_xyz_3 Comp;
|
||
|
|
||
|
// We first copy everything in a vector to only require an InputIterator.
|
||
|
std::vector<Triangle> triangles(begin, end);
|
||
|
typedef typename std::vector<Triangle>::const_iterator Tit;
|
||
|
|
||
|
// Put the points in a map and a vector.
|
||
|
// The index of a point in the vector is the value associated
|
||
|
// to it in the map.
|
||
|
typedef std::map<Point, int, Comp> Point_map;
|
||
|
Point_map point_map(Kernel().less_xyz_3_object());
|
||
|
std::vector<Point> points;
|
||
|
for (Tit i = triangles.begin(); i != triangles.end(); ++i)
|
||
|
for (int j = 0; j < 3; ++j)
|
||
|
if (point_map.insert(typename Point_map::value_type(i->vertex(j),
|
||
|
points.size())).second)
|
||
|
points.push_back(i->vertex(j));
|
||
|
|
||
|
bool ascii_bak = get_ascii_mode();
|
||
|
bool raw_bak = set_raw(true);
|
||
|
|
||
|
// Header.
|
||
|
set_binary_mode();
|
||
|
(*this) << "(geometry " << get_new_id("triangles")
|
||
|
<< " {appearance {}{ OFF BINARY\n"
|
||
|
<< points.size() << triangles.size() << 0;
|
||
|
|
||
|
// Points coordinates.
|
||
|
std::copy(points.begin(), points.end(),
|
||
|
Ostream_iterator<Point, Geomview_stream>(*this));
|
||
|
|
||
|
// Triangles vertices indices.
|
||
|
for (Tit tit = triangles.begin(); tit != triangles.end(); ++tit) {
|
||
|
(*this) << 3;
|
||
|
for (int j = 0; j < 3; ++j)
|
||
|
(*this) << point_map[tit->vertex(j)];
|
||
|
(*this) << 0; // without color.
|
||
|
}
|
||
|
// Footer.
|
||
|
(*this) << "}})";
|
||
|
|
||
|
set_raw(raw_bak);
|
||
|
set_ascii_mode(ascii_bak);
|
||
|
}
|
||
|
|
||
|
#if defined CGAL_TRIANGLE_2_H && \
|
||
|
!defined CGAL_GV_OUT_TRIANGLE_2_H
|
||
|
#define CGAL_GV_OUT_TRIANGLE_2_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Triangle_2<R> &triangle)
|
||
|
{
|
||
|
output_triangle(gv, triangle);
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined CGAL_TRIANGLE_3_H && \
|
||
|
!defined CGAL_GV_OUT_TRIANGLE_3_H
|
||
|
#define CGAL_GV_OUT_TRIANGLE_3_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Triangle_3<R> &triangle)
|
||
|
{
|
||
|
output_triangle(gv, triangle);
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined CGAL_TETRAHEDRON_3_H && \
|
||
|
!defined CGAL_GV_OUT_TETRAHEDRON_3_H
|
||
|
#define CGAL_GV_OUT_TETRAHEDRON_3_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Tetrahedron_3<R> &t)
|
||
|
{
|
||
|
bool ascii_bak = gv.set_ascii_mode();
|
||
|
gv << "(geometry " << gv.get_new_id("Tetra")
|
||
|
<< " {appearance {}{ ";
|
||
|
gv.set_binary_mode();
|
||
|
gv << "OFF BINARY\n"
|
||
|
|
||
|
// it has 4 vertices, 4 face and 6 edges
|
||
|
<< 4 << 4 << 6 ;
|
||
|
|
||
|
// the vertices
|
||
|
bool raw_bak = gv.set_raw(true);
|
||
|
for(int i=0; i<4; i++)
|
||
|
gv << t[i];
|
||
|
gv.set_raw(raw_bak);
|
||
|
|
||
|
// the faces
|
||
|
double r = gv.fcr(),
|
||
|
g = gv.fcg(),
|
||
|
b = gv.fcb();
|
||
|
gv << 3 << 0 << 1 << 2 << 4 << r << g << b << 1.0
|
||
|
<< 3 << 3 << 0 << 1 << 4 << r << g << b << 1.0
|
||
|
<< 3 << 3 << 1 << 2 << 4 << r << g << b << 1.0
|
||
|
<< 3 << 3 << 0 << 2 << 4 << r << g << b << 1.0
|
||
|
<< "}})";
|
||
|
gv.set_ascii_mode(ascii_bak);
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined CGAL_SPHERE_3_H && \
|
||
|
!defined CGAL_GV_OUT_SPHERE_3_H
|
||
|
#define CGAL_GV_OUT_SPHERE_3_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Sphere_3<R> &S)
|
||
|
{
|
||
|
bool ascii_bak = gv.set_ascii_mode();
|
||
|
gv << "(geometry " << gv.get_new_id("Sph")
|
||
|
<< " {appearance {+edge material {edgecolor "
|
||
|
<< gv.ecr() << gv.ecg() << gv.ecb() << "} shading constant}{ "
|
||
|
<< "SPHERE\n"
|
||
|
<< std::sqrt(CGAL::to_double(S.squared_radius())) << "\n";
|
||
|
|
||
|
bool raw_bak = gv.set_raw(true);
|
||
|
gv << Point_3<R>(S.center()) << "}})";
|
||
|
gv.set_raw(raw_bak);
|
||
|
gv.set_ascii_mode(ascii_bak);
|
||
|
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined CGAL_RAY_2_H && \
|
||
|
!defined CGAL_GV_OUT_RAY_2_H
|
||
|
#define CGAL_GV_OUT_RAY_2_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Ray_2<R> &r)
|
||
|
{
|
||
|
// Note: it won't work if double is not convertible to an RT...
|
||
|
const Bbox_3 & bb = gv.get_bbox();
|
||
|
Object result = intersection(Iso_rectangle_2<R>(
|
||
|
Point_2<R>(bb.xmin(), bb.ymin()),
|
||
|
Point_2<R>(bb.xmax(), bb.ymax())), r);
|
||
|
Point_2<R> ipoint;
|
||
|
Segment_2<R> iseg;
|
||
|
if (assign(ipoint, result))
|
||
|
gv << ipoint;
|
||
|
else if (assign(iseg, result))
|
||
|
gv << iseg;
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined CGAL_LINE_2_H && \
|
||
|
!defined CGAL_GV_OUT_LINE_2_H
|
||
|
#define CGAL_GV_OUT_LINE_2_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Line_2<R> &r)
|
||
|
{
|
||
|
// Note: it won't work if double is not convertible to an RT...
|
||
|
const Bbox_3 & bb = gv.get_bbox();
|
||
|
Object result = intersection(Iso_rectangle_2<R>(
|
||
|
Point_2<R>(bb.xmin(), bb.ymin()),
|
||
|
Point_2<R>(bb.xmax(), bb.ymax())), r);
|
||
|
Point_2<R> ipoint;
|
||
|
Segment_2<R> iseg;
|
||
|
if (assign(ipoint, result))
|
||
|
gv << ipoint;
|
||
|
else if (assign(iseg, result))
|
||
|
gv << iseg;
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// Ray and Line drawing should be done by intersecting them with the BBox
|
||
|
// of the Geomview_stream. But for now we take the easy approach.
|
||
|
|
||
|
#if defined CGAL_RAY_3_H && \
|
||
|
!defined CGAL_GV_OUT_RAY_3_H
|
||
|
#define CGAL_GV_OUT_RAY_3_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Ray_3<R> &r)
|
||
|
{
|
||
|
typename R::Segment_3 s(r.source(), r.point(1));
|
||
|
gv << s;
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined CGAL_LINE_3_H && \
|
||
|
!defined CGAL_GV_OUT_LINE_3_H
|
||
|
#define CGAL_GV_OUT_LINE_3_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Line_3<R> &r)
|
||
|
{
|
||
|
typename R::Segment_3 s(r.point(-1), r.point(1));
|
||
|
gv << s;
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
CGAL_EXPORT Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Bbox_2 &bbox);
|
||
|
|
||
|
CGAL_EXPORT Geomview_stream&
|
||
|
operator<<(Geomview_stream &gv, const Bbox_3 &bbox);
|
||
|
|
||
|
#if defined CGAL_POINT_3_H && !defined CGAL_GV_IN_POINT_3_H
|
||
|
#define CGAL_GV_IN_POINT_3_H
|
||
|
template < class R >
|
||
|
Geomview_stream&
|
||
|
operator>>(Geomview_stream &gv, Point_3<R> &point)
|
||
|
{
|
||
|
const char *gclpick =
|
||
|
"(pick world pickplane * nil nil nil nil nil nil nil)";
|
||
|
|
||
|
bool ascii_bak = gv.set_ascii_mode();
|
||
|
gv << "(pickable pickplane yes) (ui-target pickplane yes)"
|
||
|
<< "(interest " << gclpick << ")";
|
||
|
|
||
|
char sexpr[1024];
|
||
|
gv >> sexpr; // this reads a gcl expression
|
||
|
|
||
|
const char* pickpoint = Geomview_stream::nth(sexpr, 3);
|
||
|
// this gives something as: (0.0607123 0.0607125 4.76837e-07 0.529628)
|
||
|
double x, y, z, w;
|
||
|
Geomview_stream::parse_point(pickpoint, x, y, z, w);
|
||
|
point = Point_3<R>(x, y, z, w);
|
||
|
|
||
|
// we echo the input
|
||
|
if (gv.get_echo())
|
||
|
gv << point;
|
||
|
|
||
|
// we are done and tell geomview to stop sending pick events
|
||
|
gv << "(uninterest " << gclpick << ") (pickable pickplane no)";
|
||
|
gv.set_ascii_mode(ascii_bak);
|
||
|
|
||
|
return gv;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
} //namespace CGAL
|
||
|
|
||
|
#ifdef CGAL_HEADER_ONLY
|
||
|
#include <CGAL/IO/Geomview_stream_impl.h>
|
||
|
#endif // CGAL_HEADER_ONLY
|
||
|
|
||
|
#endif // CGAL_USE_GEOMVIEW
|
||
|
|
||
|
#endif // CGAL_GEOMVIEW_STREAM_H
|