code: function(cagish) {
              this.verify();
              function getCag(cagish, connector) {
                  if (typeof cagish == "function") {
                      cagish = cagish(connector.point, connector.axisvector, connector.normalvector);
                  }
                  return cagish;
              }
  
              var polygons = [], currCag;
              var prevConnector = this.connectors_[this.connectors_.length - 1];
              var prevCag = getCag(cagish, prevConnector);
              // add walls
              this.connectors_.forEach(function(connector, notFirst) {
                  currCag = getCag(cagish, connector);
                  if (notFirst || this.closed) {
                      polygons.push.apply(polygons, prevCag._toWallPolygons({
                          toConnector1: prevConnector, toConnector2: connector, cag: currCag}));
                  } else {
                      // it is the first, and shape not closed -> build start wall
                      polygons.push.apply(polygons,
                          currCag._toPlanePolygons({toConnector: connector, flipped: true}));
                  }
                  if (notFirst == this.connectors_.length - 1 && !this.closed) {
                      // build end wall
                      polygons.push.apply(polygons,
                          currCag._toPlanePolygons({toConnector: connector}));
                  }
                  prevCag = currCag;
                  prevConnector = connector;
              }, this);
              return CSG.fromPolygons(polygons).reTesselated().canonicalized();
          }
docs: /*
  arguments: cagish: a cag or a function(connector) returning a cag
  closed: whether the 3d path defined by connectors location
  should be closed or stay open
  Note: don't duplicate connectors in the path
  TODO: consider an option "maySelfIntersect" to close & force union all single segments