/** * @brief Clones this Universe and all of the Cells within it and returns it * @return a pointer to the Universe clone */ Universe* Universe::clone() { log_printf(DEBUG, "Cloning Universe %d", _id); /* Instantiate new Universe clone */ Universe* clone = new Universe(universe_id()); /* Loop over Cells in Universe and clone each one */ std::map<int, Cell*>::iterator iter1; for (iter1 = _cells.begin(); iter1 != _cells.end(); ++iter1) { /* If the Cell is filled with a Material, clone it */ if ((*iter1).second->getType() == MATERIAL) { /* Clone the Cell */ CellBasic* parent = static_cast<CellBasic*>((*iter1).second); CellBasic* cell_clone = parent->clone(); /* Add Cell clone to the list */ clone->addCell(cell_clone); cell_clone->setUniverse(clone->getId()); } /* Throw error message if Cell is FILL type */ else { log_printf(ERROR, "Unable to clone Universe %d since it contains Cell %d" "which is filled with a Universe rather than a Material"); } } return clone; }
// ---------------------------------------------------------------------------- // void HttpRestServices::query_venue_describe( Venue* venue, DMXHttpSession* session, CString& response, LPCSTR data ) { JsonBuilder json( response ); json.startObject(); json.add( "name", venue->getName() ); json.add( "description", venue->getDescription() ); json.add( "auto_blackout", venue->getAutoBlackoutMS() ); json.add( "audio_capture_device", venue->getAudioCaptureDevice() ); json.add( "audio_sample_size", venue->getAudioSampleSize() ); json.add( "audio_boost", venue->getAudioBoost() ); json.add( "audio_boost_floor", venue->getAudioBoostFloor() ); json.add( "track_fixtures", venue->isTrackFixtures() ); json.startArray( "ports" ); for ( int i=1; i <= 12; i++ ) { CString com_port; com_port.Format( "com%d", i ); json.add( com_port ); } json.endArray( "ports" ); json.startArray("driver_types"); json.add( "Enttec USB Pro"); json.add( "Open DMX"); json.add( "Philips Hue"); json.endArray("driver_types"); json.startArray( "universes" ); UniversePtrArray universes = venue->getUniverses(); for ( UniversePtrArray::iterator it=universes.begin(); it != universes.end(); ++it ) { Universe* universe = (*it); json.startObject( ); json.add( "id", universe->getId() ); json.add( "type", universe->getType() ); json.add( "dmx_config", universe->getDmxConfig() ); json.add( "packet_delay_ms", universe->getDmxPacketDelayMS() ); json.add( "minimum_delay_ms", universe->getDmxMinimumDelayMS() ); json.endObject( ); } json.endArray( "universes" ); json.startArray( "capture_devices" ); for ( AudioCaptureDeviceArray::iterator it=AudioInputStream::audioCaptureDevices.begin(); it != AudioInputStream::audioCaptureDevices.end(); ++it ) json.add( (*it).m_friendly_name ); json.endArray( "capture_devices" ); json.endObject(); }
/** * @brief Finds the next Cell for a LocalCoords object along a trajectory * defined by some angle (in radians from 0 to pi). * @details The method will update the LocalCoords passed in as an argument * to be the one at the boundary of the next Cell crossed along the * given trajectory. It will do this by recursively building a linked * list of LocalCoords from the LocalCoords passed in as an argument * down to the lowest level Cell found. In the process it will set * the local coordinates for each LocalCoords in the linked list for * the Lattice or Universe that it is in. If the LocalCoords is * outside the bounds of the Lattice or on the boundaries this method * will return NULL; otherwise it will return a pointer to the Cell * that the LocalCoords will reach next along its trajectory. * @param coords pointer to a LocalCoords object * @param angle the angle of the trajectory * @param universes a map of all of the Universes passed in by the Geometry * @return a pointer to a Cell if found, NULL if no cell found */ Cell* Lattice::findNextLatticeCell(LocalCoords* coords, double angle, std::map<int, Universe*> universes) { /* Tests the upper, lower, left and right Lattice Cells adjacent to * the LocalCoord and uses the one with the shortest distance from * the current location of the LocalCoord */ /* Initial distance is infinity */ double distance = std::numeric_limits<double>::infinity(); /* Current minimum distance */ double d; /* Properties of the current LocalCoords */ double x0 = coords->getX(); double y0 = coords->getY(); int lattice_x = coords->getLatticeX(); int lattice_y = coords->getLatticeY(); /* Slope of trajectory */ double m = sin(angle) / cos(angle); /* Properties of the new location for LocalCoords */ /* Current point of minimum distance */ double x_curr, y_curr; /* x-coordinate on new Lattice cell */ double x_new = x0; /* y-coordinate on new Lattice cell */ double y_new = x0; /* New x Lattice cell index */ int new_lattice_x; /* New y Lattice cell index */ int new_lattice_y; /* Test Point for computing distance */ Point test; /* Check lower Lattice cell */ if (lattice_y >= 0 && angle >= M_PI) { y_curr = (lattice_y - _num_y/2.0) * _width_y; x_curr = x0 + (y_curr - y0) / m; test.setCoords(x_curr, y_curr); /* Check if the test Point is within the bounds of the Lattice */ if (withinBounds(&test)) { d = test.distanceToPoint(coords->getPoint()); /* Check if distance to test Point is current minimum */ if (d < distance) { distance = d; x_new = x_curr; y_new = y_curr; } } } /* Upper Lattice cell */ if (lattice_y <= _num_y-1 && angle <= M_PI) { y_curr = (lattice_y - _num_y/2.0 + 1) * _width_y; x_curr = x0 + (y_curr - y0) / m; test.setCoords(x_curr, y_curr); /* Check if the test Point is within the bounds of the Lattice */ if (withinBounds(&test)) { d = test.distanceToPoint(coords->getPoint()); /* Check if distance to test Point is current minimum */ if (d < distance) { distance = d; x_new = x_curr; y_new = y_curr; } } } /* Left Lattice cell */ if (lattice_x >= 0 && (angle >= M_PI/2 && angle <= 3*M_PI/2)) { x_curr = (lattice_x - _num_x/2.0) * _width_x; y_curr = y0 + m * (x_curr - x0); test.setCoords(x_curr, y_curr); /* Check if the test Point is within the bounds of the Lattice */ if (withinBounds(&test)) { d = test.distanceToPoint(coords->getPoint()); /* Check if distance to test Point is current minimum */ if (d < distance) { distance = d; x_new = x_curr; y_new = y_curr; } } } /* Right Lattice cell */ if (lattice_x <= _num_x-1 && (angle <= M_PI/2 || angle >= 3*M_PI/2)) { x_curr = (lattice_x - _num_x/2.0 + 1) * _width_x; y_curr = y0 + m * (x_curr - x0); test.setCoords(x_curr, y_curr); /* Check if the test Point is within the bounds of the Lattice */ if (withinBounds(&test)) { d = test.distanceToPoint(coords->getPoint()); /* Check if distance to test Point is current minimum */ if (d < distance) { distance = d; x_new = x_curr; y_new = y_curr; } } } /* If no Point was found on the Lattice cell, then the LocalCoords was * already on the boundary of the Lattice */ if (distance == INFINITY) return NULL; /* Otherwise a Point was found inside a new Lattice cell */ else { /* Update the Localcoords location to the Point on the new Lattice cell * plus a small bit to ensure that its coordinates are inside cell */ double delta_x = (x_new - coords->getX()) + cos(angle) * TINY_MOVE; double delta_y = (y_new - coords->getY()) + sin(angle) * TINY_MOVE; coords->adjustCoords(delta_x, delta_y); /* Compute the x and y indices for the new Lattice cell */ new_lattice_x = (int)floor((coords->getX() - _origin.getX())/_width_x); new_lattice_y = (int)floor((coords->getY() - _origin.getY())/_width_y); /* Check if the LocalCoord is on the lattice boundaries and if so adjust * x or y Lattice cell indices i */ if (fabs(fabs(coords->getX()) - _num_x*_width_x*0.5) < ON_LATTICE_CELL_THRESH) { if (coords->getX() > 0) new_lattice_x = _num_x - 1; else new_lattice_x = 0; } if (fabs(fabs(coords->getY()) - _num_y*_width_y*0.5) < ON_LATTICE_CELL_THRESH) { if (coords->getY() > 0) new_lattice_y = _num_y - 1; else new_lattice_y = 0; } /* Check if new Lattice cell indices are within the bounds, if not, * new LocalCoords is now on the boundary of the Lattice */ if (new_lattice_x >= _num_x || new_lattice_x < 0) return NULL; else if (new_lattice_y >= _num_y || new_lattice_y < 0) return NULL; /* New LocalCoords is still within the interior of the Lattice */ else { /* Update the LocalCoords Lattice cell indices */ coords->setLatticeX(new_lattice_x); coords->setLatticeY(new_lattice_y); /* Move to next lowest level Universe */ coords->prune(); Universe* univ = _universes.at(new_lattice_y).at(new_lattice_x).second; LocalCoords* next_coords; /* Compute local position of Point in next level Universe */ double nextX = coords->getX() - (_origin.getX() + (new_lattice_x + 0.5) * _width_x); double nextY = coords->getY() - (_origin.getY() + (new_lattice_y + 0.5) * _width_y); /* Set the coordinates at the next level LocalCoord */ next_coords = new LocalCoords(nextX, nextY); next_coords->setPrev(coords); coords->setNext(next_coords); next_coords->setUniverse(univ->getId()); /* Search lower level Universe */ return findCell(coords, universes); } } }