FAUST compiler  0.9.9.6b8
seqSchema.cpp
Go to the documentation of this file.
1 /************************************************************************
2  ************************************************************************
3  FAUST compiler
4  Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5  ---------------------------------------------------------------------
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  ************************************************************************
20  ************************************************************************/
21 
22 
23 #include "seqSchema.h"
24 #include <iostream>
25 #include <assert.h>
26 
27 using namespace std;
28 
30 
31 static double computeHorzGap(schema* a, schema* b);
32 static int direction(const point& a, const point& b);
33 
34 
35 //----------------------------INTERFACE--------------------------------
36 
44 {
45  unsigned int o = s1->outputs();
46  unsigned int i = s2->inputs();
47 
48  schema* a = (o < i) ? makeParSchema(s1, makeCableSchema(i-o)) : s1;
49  schema* b = (o > i) ? makeParSchema(s2, makeCableSchema(o-i)) : s2;
50 
51  return new seqSchema(a, b, computeHorzGap(a,b));
52 }
53 
54 
55 
56 //-----------------------IMPLEMENTATION------------------------------
57 
62 seqSchema::seqSchema (schema* s1, schema* s2, double hgap)
63  : schema( s1->inputs(),
64  s2->outputs(),
65  s1->width() + hgap + s2->width(),
66  max(s1->height(), s2->height()) ),
67  fSchema1(s1),
68  fSchema2(s2),
69  fHorzGap(hgap)
70 {
71  assert(s1->outputs() == s2->inputs());
72 }
73 
74 
75 //-----------------------placement------------------------------
76 
77 
82 void seqSchema::place(double ox, double oy, int orientation)
83 {
84  beginPlace(ox, oy, orientation);
85 
86  double y1 = max(0.0, 0.5*(fSchema2->height() - fSchema1->height()));
87  double y2 = max(0.0, 0.5*(fSchema1->height() - fSchema2->height()));
88 
89  if (orientation == kLeftRight) {
90  fSchema1->place(ox, oy+y1, orientation);
92  } else {
93  fSchema2->place(ox, oy+y2, orientation);
95  }
96  endPlace();
97 }
98 
99 
103 point seqSchema::inputPoint(unsigned int i) const
104 {
105  return fSchema1->inputPoint(i);
106 }
107 
108 
112 point seqSchema::outputPoint(unsigned int i) const
113 {
114  return fSchema2->outputPoint(i);
115 }
116 
117 
118 
119 //--------------------------drawing------------------------------
120 
121 
126 {
127  assert(placed());
128  assert(fSchema1->outputs() == fSchema2->inputs());
129 
130  fSchema1->draw(dev);
131  fSchema2->draw(dev);
132  //drawInternalWires(dev);
133 }
134 
139 {
140  assert(placed());
141  assert(fSchema1->outputs() == fSchema2->inputs());
142 
146 }
147 
148 
155 {
156  assert (fSchema1->outputs() == fSchema2->inputs());
157 
158  const int N = fSchema1->outputs();
159  double dx = 0;
160  double mx = 0;
161  int dir =-1;
162 
163  if (orientation() == kLeftRight) {
164  // draw left right cables
165  for (int i=0; i<N; i++) {
166  point src = fSchema1->outputPoint(i);
167  point dst = fSchema2->inputPoint(i);
168 
169  int d = direction(src,dst);
170  if (d != dir) {
171  // compute attributes of new direction
172  switch (d) {
173  case kUpDir : mx = 0; dx = dWire; break;
174  case kDownDir : mx = fHorzGap; dx = -dWire; break;
175  default : mx = 0; dx = 0; break;
176  }
177  dir = d;
178  } else {
179  // move in same direction
180  mx = mx +dx;
181  }
182  if (src.y == dst.y) {
183  // draw straight cable
184  dev.trait(src.x, src.y, dst.x, dst.y);
185  } else {
186  // draw zizag cable
187  dev.trait(src.x, src.y, src.x+mx, src.y);
188  dev.trait(src.x+mx, src.y, src.x+mx, dst.y);
189  dev.trait(src.x+mx, dst.y, dst.x, dst.y);
190  }
191 
192  }
193  } else {
194  // draw right left cables
195  for (int i=0; i<N; i++) {
196  point src = fSchema1->outputPoint(i);
197  point dst = fSchema2->inputPoint(i);
198 
199  int d = direction(src,dst);
200  if (d != dir) {
201  // compute attributes of new direction
202  switch (d) {
203  case kUpDir : mx = -fHorzGap; dx = dWire; break;
204  case kDownDir : mx = 0; dx = -dWire; break;
205  default : mx = 0; dx = 0; break;
206  }
207  dir = d;
208  } else {
209  // move in same direction
210  mx = mx +dx;
211  }
212  if (src.y == dst.y) {
213  // draw straight cable
214  dev.trait(src.x, src.y, dst.x, dst.y);
215  } else {
216  // draw zizag cable
217  dev.trait(src.x, src.y, src.x+mx, src.y);
218  dev.trait(src.x+mx, src.y, src.x+mx, dst.y);
219  dev.trait(src.x+mx, dst.y, dst.x, dst.y);
220  }
221 
222  }
223  }
224 }
225 
226 
227 
234 {
235  assert (fSchema1->outputs() == fSchema2->inputs());
236 
237  const int N = fSchema1->outputs();
238  double dx = 0;
239  double mx = 0;
240  int dir =-1;
241 
242  if (orientation() == kLeftRight) {
243  // draw left right cables
244  for (int i=0; i<N; i++) {
245  point src = fSchema1->outputPoint(i);
246  point dst = fSchema2->inputPoint(i);
247 
248  int d = direction(src,dst);
249  if (d != dir) {
250  // compute attributes of new direction
251  switch (d) {
252  case kUpDir : mx = 0; dx = dWire; break;
253  case kDownDir : mx = fHorzGap; dx = -dWire; break;
254  default : mx = 0; dx = 0; break;
255  }
256  dir = d;
257  } else {
258  // move in same direction
259  mx = mx +dx;
260  }
261  if (src.y == dst.y) {
262  // draw straight cable
263  c.addTrait(trait(point(src.x, src.y), point(dst.x, dst.y)));
264  } else {
265  // draw zizag cable
266  c.addTrait(trait(point(src.x, src.y), point(src.x+mx, src.y)));
267  c.addTrait(trait(point(src.x+mx, src.y), point(src.x+mx, dst.y)));
268  c.addTrait(trait(point(src.x+mx, dst.y), point(dst.x, dst.y)));
269  }
270 
271  }
272  } else {
273  // draw right left cables
274  for (int i=0; i<N; i++) {
275  point src = fSchema1->outputPoint(i);
276  point dst = fSchema2->inputPoint(i);
277 
278  int d = direction(src,dst);
279  if (d != dir) {
280  // compute attributes of new direction
281  switch (d) {
282  case kUpDir : mx = -fHorzGap; dx = dWire; break;
283  case kDownDir : mx = 0; dx = -dWire; break;
284  default : mx = 0; dx = 0; break;
285  }
286  dir = d;
287  } else {
288  // move in same direction
289  mx = mx +dx;
290  }
291  if (src.y == dst.y) {
292  // draw straight cable
293  c.addTrait(trait(point(src.x, src.y), point(dst.x, dst.y)));
294  } else {
295  // draw zizag cable
296  c.addTrait(trait(point(src.x, src.y), point(src.x+mx, src.y)));
297  c.addTrait(trait(point(src.x+mx, src.y), point(src.x+mx, dst.y)));
298  c.addTrait(trait(point(src.x+mx, dst.y), point(dst.x, dst.y)));
299  }
300 
301  }
302  }
303 }
304 
305 //--------------------------helpers------------------------------
306 
307 
308 
313 static int direction(const point& a, const point& b)
314 {
315  if (a.y > b.y) return kUpDir; // upward connections
316  if (a.y < b.y) return kDownDir; // downward connection
317  return kHorDir; // horizontal connections
318 }
319 
325 static double computeHorzGap(schema* a, schema* b)
326 {
327  assert(a->outputs() == b->inputs());
328 
329  if (a->outputs() == 0) {
330  return 0;
331  } else {
332  // store here the size of the largest group for each direction
333  int MaxGroupSize[3]; for(int i=0; i<3; i++) MaxGroupSize[i]=0;
334 
335  // place a and b to have valid connection points
336  double ya = max(0.0, 0.5*(b->height() - a->height()));
337  double yb = max(0.0, 0.5*(a->height() - b->height()));
338  a->place(0,ya,kLeftRight);
339  b->place(0,yb,kLeftRight);
340 
341  // init current group direction and size
342  int gdir = direction(a->outputPoint(0), b->inputPoint(0));
343  int gsize = 1;
344 
345  // analyze direction of remaining points
346  for (unsigned int i=1; i<a->outputs(); i++) {
347  int d = direction(a->outputPoint(i), b->inputPoint(i));
348  if (d == gdir) {
349  gsize++;
350  } else {
351  if (gsize > MaxGroupSize[gdir]) MaxGroupSize[gdir]=gsize;
352  gsize = 1;
353  gdir = d;
354  }
355  }
356 
357  // update for last group
358  if (gsize > MaxGroupSize[gdir]) MaxGroupSize[gdir]=gsize;
359 
360  // the gap required for the connections
361  return dWire * max(MaxGroupSize[kUpDir],MaxGroupSize[kDownDir]);
362  }
363 }
void collectInternalWires(collector &c)
Draw the internal wires aligning the vertical segments in a symetric way when possible.
Definition: seqSchema.cpp:233
void addTrait(const trait &t)
Definition: schema.h:84
void endPlace()
Definition: schema.h:134
Definition: schema.h:56
unsigned int outputs() const
Definition: schema.h:129
const double dWire
distance between two wires
Definition: schema.h:33
virtual point inputPoint(unsigned int i) const =0
virtual void collectTraits(collector &c)
Draw the two components as well as the internal wires.
Definition: seqSchema.cpp:138
void beginPlace(double x, double y, int orientation)
Definition: schema.h:132
virtual void draw(device &dev)=0
schema * makeParSchema(schema *s1, schema *s2)
Definition: parSchema.cpp:28
virtual void collectTraits(collector &c)=0
unsigned int inputs() const
Definition: schema.h:128
virtual point inputPoint(unsigned int i) const
The input points are the input points of the first component.
Definition: seqSchema.cpp:103
double max(double x, double y)
Definition: interval.hh:60
static int direction(const point &a, const point &b)
Compute the direction of a connection.
Definition: seqSchema.cpp:313
static double computeHorzGap(schema *a, schema *b)
Compute the horizontal gap needed to draw the internal wires.
Definition: seqSchema.cpp:325
double width() const
Definition: schema.h:126
double y
Definition: schema.h:43
schema * fSchema2
Definition: seqSchema.h:39
bool placed() const
Definition: schema.h:137
seqSchema(schema *s1, schema *s2, double hgap)
Constructor for a sequential schema (s1:s2).
Definition: seqSchema.cpp:62
Definition: device.h:32
virtual void draw(device &dev)
Draw the two components as well as the internal wires.
Definition: seqSchema.cpp:125
Sequential composition.
Definition: seqSchema.h:36
int orientation() const
Definition: schema.h:140
virtual void place(double ox, double oy, int orientation)
Place the two components horizontally with enough space for the connections.
Definition: seqSchema.cpp:82
void drawInternalWires(device &dev)
Draw the internal wires aligning the vertical segments in a symetric way when possible.
Definition: seqSchema.cpp:154
virtual void place(double x, double y, int orientation)=0
double x
Definition: schema.h:42
Definition: schema.h:40
virtual point outputPoint(unsigned int i) const =0
An abstract block diagram schema.
Definition: schema.h:97
double height() const
Definition: schema.h:127
virtual point outputPoint(unsigned int i) const
The output points are the output points of the second component.
Definition: seqSchema.cpp:112
schema * makeCableSchema(unsigned int n)
Build n cables in parallel.
Definition: cableSchema.cpp:32
schema * makeSeqSchema(schema *s1, schema *s2)
Make a sequential schema.
Definition: seqSchema.cpp:43
double fHorzGap
Definition: seqSchema.h:40
virtual void trait(double x1, double y1, double x2, double y2)=0
schema * fSchema1
Definition: seqSchema.h:38