void LLVOPartGroup::getGeometry(S32 idx, LLStrider<LLVector4a>& verticesp, LLStrider<LLVector3>& normalsp, LLStrider<LLVector2>& texcoordsp, LLStrider<LLColor4U>& colorsp, LLStrider<LLColor4U>& emissivep, LLStrider<U16>& indicesp) { if (idx >= (S32) mViewerPartGroupp->mParticles.size()) { return; } const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx])); getGeometry(part, verticesp); LLColor4U pcolor; LLColor4U color = part.mColor; LLColor4U pglow; if (part.mFlags & LLPartData::LL_PART_RIBBON_MASK) { //make sure color blends properly if (part.mParent) { pglow = part.mParent->mGlow; pcolor = part.mParent->mColor; } else { pglow = LLColor4U(0, 0, 0, (U8) llround(255.f*part.mStartGlow)); pcolor = part.mStartColor; } } else { pglow = part.mGlow; pcolor = color; } *colorsp++ = pcolor; *colorsp++ = pcolor; *colorsp++ = color; *colorsp++ = color; //Only add emissive attributes if glowing (doing it for all particles is INCREDIBLY inefficient as it leads to a second, slower, render pass.) if (pglow.mV[3] > F_ALMOST_ZERO || part.mGlow.mV[3] > F_ALMOST_ZERO) { //only write glow if it is not zero *emissivep++ = pglow; *emissivep++ = pglow; *emissivep++ = part.mGlow; *emissivep++ = part.mGlow; } if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK)) { //not fullbright, needs normal LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis(); *normalsp++ = normal; *normalsp++ = normal; *normalsp++ = normal; *normalsp++ = normal; } }
std::shared_ptr<te::mem::DataSet> terrama2::services::analysis::core::createAggregationBuffer( std::vector<uint32_t>& indexes, std::shared_ptr<ContextDataSeries> contextDataSeries, Buffer buffer, StatisticOperation aggregationStatisticOperation, const std::string& attribute) { std::shared_ptr<te::mem::DataSet> dsOut; if(indexes.empty()) return dsOut; // Creates memory dataset for buffer te::da::DataSetType* dt = new te::da::DataSetType("buffer"); auto syncDs = contextDataSeries->series.syncDataSet; auto sampleGeom = syncDs->getGeometry(0, contextDataSeries->geometryPos); int geomSampleSrid = sampleGeom->getSRID(); te::gm::GeometryProperty* prop = new te::gm::GeometryProperty("geom", 0, te::gm::MultiPolygonType, true); prop->setSRID(geomSampleSrid); dt->add(prop); te::dt::SimpleProperty* prop02 = new te::dt::SimpleProperty("attribute", te::dt::DOUBLE_TYPE, true); dt->add(prop02); dsOut.reset(new te::mem::DataSet(dt)); std::shared_ptr<te::gm::Envelope> box(syncDs->getExtent(contextDataSeries->geometryPos)); if(buffer.unit.empty()) buffer.unit = "m"; // Inserts each geometry in the rtree, if there is a conflict, it makes the union of the two geometries te::sam::rtree::Index<OccurrenceAggregation*, 4> rtree; for(size_t i = 0; i < indexes.size(); ++i) { auto geom = syncDs->getGeometry(indexes[i], contextDataSeries->geometryPos); double distance = terrama2::core::convertDistanceUnit(buffer.distance, buffer.unit, "METER"); std::unique_ptr<te::gm::Geometry> tempGeom(dynamic_cast<te::gm::Geometry*>(geom.get()->clone())); if(!tempGeom) { QString errMsg(QObject::tr("Invalid geometry in dataset: ").arg(contextDataSeries->series.dataSet->id)); throw terrama2::InvalidArgumentException() << ErrorDescription(errMsg); } int utmSrid = terrama2::core::getUTMSrid(tempGeom.get()); // Converts to UTM in order to create buffer in meters if(tempGeom->getSRID() != utmSrid) { tempGeom->transform(utmSrid); } std::unique_ptr<te::gm::Geometry> aggBuffer(tempGeom->buffer(distance, 16, te::gm::CapButtType)); aggBuffer->setSRID(utmSrid); // Converts buffer to DataSet SRID in order to compare with the occurrences in the rtree aggBuffer->transform(geomSampleSrid); std::vector<OccurrenceAggregation*> vec; bool aggregated = false; // Search for occurrences in the same area rtree.search(*(aggBuffer->getMBR()), vec); for(std::size_t t = 0; t < vec.size(); ++t) { OccurrenceAggregation* occurrenceAggregation = vec[t]; // If the an intersection is found, makes the union of the two geometries and mark the index. if(aggBuffer->intersects(occurrenceAggregation->buffer.get())) { rtree.remove(*(occurrenceAggregation->buffer->getMBR()), occurrenceAggregation); occurrenceAggregation->buffer.reset(aggBuffer->Union(occurrenceAggregation->buffer.get())); occurrenceAggregation->indexes.push_back(i); rtree.insert(*(occurrenceAggregation->buffer->getMBR()), occurrenceAggregation); aggregated = true; } } if(!aggregated) { OccurrenceAggregation* occurrenceAggregation = new OccurrenceAggregation(); occurrenceAggregation->buffer.reset(aggBuffer.release()); occurrenceAggregation->indexes.push_back(i); rtree.insert(*(occurrenceAggregation->buffer->getMBR()), occurrenceAggregation); } } // Fills the memory dataset with the geometries std::vector<OccurrenceAggregation*> occurrenceAggVec; rtree.search(*(box.get()), occurrenceAggVec); int attributeType = -1; if(aggregationStatisticOperation != StatisticOperation::COUNT) { auto property = contextDataSeries->series.teDataSetType->getProperty(attribute); if(!property) { QString errMsg(QObject::tr("Invalid attribute: %1").arg(QString::fromStdString(attribute))); throw terrama2::InvalidArgumentException() << ErrorDescription(errMsg); } attributeType = property->getType(); } for(size_t i = 0; i < occurrenceAggVec.size(); i++) { OccurrenceAggregation* occurrenceAggregation = occurrenceAggVec[i]; OperatorCache cache; std::vector<double> values; values.reserve(occurrenceAggregation->indexes.size()); for(unsigned int j = 0; j < occurrenceAggregation->indexes.size(); ++j) { cache.count++; if(aggregationStatisticOperation != StatisticOperation::COUNT) { if(attribute.empty()) { QString errMsg(QObject::tr("Invalid attribute")); throw terrama2::InvalidArgumentException() << ErrorDescription(errMsg); } double value = getValue(syncDs, attribute, occurrenceAggregation->indexes[j], attributeType); values.push_back(value); cache.sum += value; if(value > cache.max) cache.max = value; if(value < cache.min) cache.min = value; } } calculateStatistics(values, cache); auto item = new te::mem::DataSetItem(dsOut.get()); item->setGeometry(0, dynamic_cast<te::gm::Geometry*>(occurrenceAggregation->buffer->clone())); item->setDouble(1, getOperationResult(cache, aggregationStatisticOperation)); dsOut->add(item); } return dsOut; }