Exemplo n.º 1
0
					//----------
					void AddScan::buildPreviewRays() {
						this->previewRays.clear();
						auto fitPoints = this->getFitPoints();

						//we should have already thrown if camera or projector is missing
						auto cameraNode = this->getInput<Scan::Graycode>()->getInput<Item::Camera>();
						auto projectorNode = this->getInput<Item::Projector>();
						
						auto cameraView = cameraNode->getViewInWorldSpace();
						auto projectorView = projectorNode->getViewInWorldSpace();

						for (auto & fitPoint : fitPoints) {
							auto cameraRay = cameraView.castCoordinate(fitPoint.camera);
							auto projectorRay = projectorView.castCoordinate(fitPoint.projector);

							this->previewRays.addVertices({ cameraRay.getStart()
								, cameraRay.getMidpoint()
								, projectorRay.getStart()
								, projectorRay.getMidpoint()
							});
							
							ofColor color(fitPoint.median);

							this->previewRays.addColors({ color
							, color
							, color
							, color });
						}

						previewRays.setMode(ofPrimitiveMode::OF_PRIMITIVE_LINES);
					}
		//----------
		void NodeThroughView::drawOnVideoOutput(const ofRectangle & viewBounds) {
			auto node = this->getInput<Node>();
			auto view = this->getInput<Item::View>();

			if (node && view) {
				view->getViewInWorldSpace().beginAsCamera(true);
				node->drawWorld();
				view->getViewInWorldSpace().endAsCamera();
			}
		}
Exemplo n.º 3
0
					//----------
					vector<AddScan::DataPoint> AddScan::getFitPoints() const {
						Utils::ScopedProcess scopedProcess("Get fit points");

						this->throwIfMissingAConnection<Scan::Graycode>();
						auto graycodeNode = this->getInput<Scan::Graycode>();

						graycodeNode->throwIfMissingAConnection<Item::Camera>();
						auto cameraNode = graycodeNode->getInput<Item::Camera>();

						this->throwIfMissingAConnection<Item::Projector>();
						auto projectorNode = this->getInput<Item::Projector>();

						auto cameraView = cameraNode->getViewInWorldSpace();
						auto projectorView = projectorNode->getViewInWorldSpace();

						auto & scanDataSet = graycodeNode->getDataSet();
						if (!scanDataSet.getHasData()) {
							throw(ofxRulr::Exception("Scan has no data"));
						}

						//start with set of data
						typedef map<uint32_t, ofxGraycode::DataSet::const_iterator> PointSet;
						PointSet activeCameraPixels;
						{
							Utils::ScopedProcess scopedProcessActivePixels("Get all active pixels", false);
							for (ofxGraycode::DataSet::const_iterator pixelIt = scanDataSet.begin(); pixelIt != scanDataSet.end(); pixelIt.operator++()) {
								auto & pixel = pixelIt.operator->();
								if (pixel.active) {
									activeCameraPixels[pixel.camera] = pixelIt;
								}
							}
						}


						//split the data into a 4x4 grid (quad tree approach would be nicer if we have more time)
						//and separate into bins of distance (higher is best)
						const uint32_t GRID_RES = 4;

						//array (per grid square) of map<distance, vector<points>> 
						map<uint8_t, vector<ofxGraycode::DataSet::const_iterator>> pixelsByDistancePerGridSquare[GRID_RES * GRID_RES];

						{
							Utils::ScopedProcess scopedProcessActivePixels("Split scan points into grid and distance bins", false);
							uint32_t gridCellWidth = cameraNode->getWidth() / GRID_RES;
							uint32_t gridCellHeight = cameraNode->getHeight() / GRID_RES;

							for (auto & point : activeCameraPixels) {
								auto & pixel = point.second.operator->();
								auto cameraXY = pixel.getCameraXY();

								int gridIndex = ((uint32_t)cameraXY.x / gridCellWidth) + ((uint32_t)cameraXY.y / gridCellHeight) * GRID_RES;
								pixelsByDistancePerGridSquare[gridIndex][pixel.distance].push_back(point.second);
							}
						}

						
						vector<AddScan::DataPoint> dataPoints;
						size_t targetSize = (float)activeCameraPixels.size() * this->parameters.includeForFitRatio;

						//accumulate fit points and remove as we go along
						{
							Utils::ScopedProcess scopedProcessAccumulatePoints("Split scan points into grid and distance bins", false);
							size_t gridSquare = 0;
							while (dataPoints.size() < targetSize) {
								auto & pointsForThisSquare = pixelsByDistancePerGridSquare[gridSquare];

								//if no bins available, continue to next square
								//remove best bin if empty
								//if no bins available, continue to next square
								//find best point
								//remove it from bin

								{
									if (pointsForThisSquare.empty()) {
										goto continueToNextSquare;
									}
									auto bestPointsIt = pointsForThisSquare.rbegin();
									while (bestPointsIt->second.empty()) {
										pointsForThisSquare.erase(bestPointsIt->first);
										if (pointsForThisSquare.empty()) {
											goto continueToNextSquare;
										}
										bestPointsIt = pointsForThisSquare.rbegin();
									}
									auto point = bestPointsIt->second.back().operator->();
									DataPoint dataPoint{
										cameraView.pixelToCoordinate(point.getCameraXY()),
										projectorView.pixelToCoordinate(point.getProjectorXY()),
										point.median
									};
									dataPoints.push_back(dataPoint);

									bestPointsIt->second.pop_back();
								}
							continueToNextSquare:
								gridSquare++;
								gridSquare %= (GRID_RES * GRID_RES);
							}
						}
						
						scopedProcess.end();

						return dataPoints;
					}