Ejemplo n.º 1
0
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;
	}
}
Ejemplo n.º 2
0
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;

}