summaryrefslogtreecommitdiff
path: root/graphics/asymptote/drawgroup.h
blob: 22aa858a962c7eb68db63290b232c5f72e974d6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*****
 * drawgroup.h
 * John Bowman
 *
 * Group elements in a picture to be deconstructed as a single object.
 *****/

#ifndef DRAWGROUP_H
#define DRAWGROUP_H

#include "drawelement.h"

namespace camp {

class drawBegin : public drawElement {
public:
  drawBegin() {}

  virtual ~drawBegin() {}

  bool begingroup() {return true;}
};

class drawEnd : public drawElement {
public:
  drawEnd() {}

  virtual ~drawEnd() {}

  bool endgroup() {return true;}
};

class drawBegin3 : public drawElementLC {
  string name;
  double compression;
  double granularity;
  bool closed;   // render the surface as one-sided; may yield faster rendering
  bool tessellate; // use tessellated mesh to store straight patches
  bool dobreak; // force breaking
  bool nobreak; // force grouping for transparent patches

  triple center;
  int interaction;
public:
  drawBegin3(string name, double compression, double granularity,
             bool closed, bool tessellate, bool dobreak, bool nobreak,
             triple center, int interaction) :
    name(name), compression(compression), granularity(granularity),
    closed(closed), tessellate(tessellate), dobreak(dobreak), nobreak(nobreak),
    center(center), interaction(interaction) {}

  virtual ~drawBegin3() {}

  bool begingroup() {return true;}
  bool begingroup3() {return true;}

  bool write(prcfile *out, unsigned int *count, double compressionlimit,
             groupsmap& groups) {
    groupmap& group=groups.back();
    if(name.empty()) name="group";
    groupmap::const_iterator p=group.find(name);

    unsigned c=(p != group.end()) ? p->second+1 : 0;
    group[name]=c;

    ostringstream buf;
    buf << name;
    if(c > 0) buf << "-" << (c+1);

    if(interaction == BILLBOARD)
      buf << "-" << (*count)++ << "\001";

    prc::PRCoptions options(compression > 0.0 ?
                            max(compression,compressionlimit) : 0.0,
                            granularity,closed,tessellate,dobreak,nobreak);

    groups.push_back(groupmap());
    const string& s=buf.str();
    out->begingroup(s.c_str(),&options,T);
    return true;
  }

  drawBegin3(const double* t, const drawBegin3 *s) :
    drawElementLC(t, s), name(s->name), compression(s->compression),
    granularity(s->granularity), closed(s->closed), tessellate(s->tessellate),
    dobreak(s->dobreak), nobreak(s->nobreak), interaction(s->interaction)  {
    center=t*s->center;
  }

  drawElement *transformed(const double* t) {
    return new drawBegin3(t,this);
  }
};

class drawEnd3 : public drawElement {
public:
  drawEnd3() {}

  virtual ~drawEnd3() {}

  bool endgroup() {return true;}
  bool endgroup3() {return true;}

  bool write(prcfile *out, unsigned int *, double, groupsmap& groups) {
    groups.pop_back();
    out->endgroup();
    return true;
  }
};

}

GC_DECLARE_PTRFREE(camp::drawBegin);
GC_DECLARE_PTRFREE(camp::drawEnd);

#endif