Exemplo n.º 1
0
double geometryUtils::computeVoronoiArea(Vertex_handle vertex) {
    double voronoiArea = 0.0;
    Vertex_circulator j;

    j = vertex->vertex_begin();

    do {
        Point_3 p11 = j->vertex()->point();
        Point_3 p12 = j->next()->vertex()->point();
        Point_3 p13 = j->next()->next()->vertex()->point();
        Vector_3 v11 = p13 - p12;
        Vector_3 v12 = p11 - p12;
        v11 = v11 / sqrt(CGAL::to_double(v11.squared_length()));
        v12 = v12 / sqrt(CGAL::to_double(v12.squared_length()));
        double alpha = acos(CGAL::to_double(v11 * v12));
        Point_3 p22 = j->opposite()->vertex()->point();
        Point_3 p23 = j->opposite()->next()->vertex()->point();
        Vector_3 v21 = p11 - p23;
        Vector_3 v22 = p22 - p23;
        v21 = v21 / sqrt(CGAL::to_double(v21.squared_length()));
        v22 = v22 / sqrt(CGAL::to_double(v22.squared_length()));

        double beta = acos(CGAL::to_double(v21 * v22));
        Vector_3 x = p13 - p11;
        double length = CGAL::to_double(x.squared_length());

        voronoiArea += (1.0 / 8.0) * (1.0 / tan(alpha) + 1.0 / tan(beta)) * length;

    } while (++j != vertex->vertex_begin());

    return voronoiArea;

};
Exemplo n.º 2
0
void rotate_points3d(const Eigen::MatrixXd& ptsin, const Point_3& center, const Vector_3& direction, double angle, Eigen::MatrixXd& ptsout)
{
	Eigen::Vector3d c(center.x(), center.y(), center.z());
    Eigen::Vector3d dir(direction.x(), direction.y(), direction.z());
    Eigen::Matrix4d rotMat = create_rotation3d_line_angle(center, direction, angle);

	ptsout.resize(ptsin.rows(), ptsin.cols() );
    ptsout = transform_point3d(ptsin, rotMat);
}
Exemplo n.º 3
0
void add_neighbourhood_to_hullPoints(pointVector& hullPoints, const Vertex_const_handle& vert, const double& tapeSize) {
	Point_3 pnt = vert->point();
	hullPoints.push_back(pnt);								// Add vertex point
	Nef_polyhedron::SVertex_const_iterator svcIt = vert->svertices_begin(), svcItEND = vert->svertices_end();
	CGAL_For_all(svcIt,svcItEND) {
		Vector_3 vecR(pnt,svcIt->target()->point());
		Vector_3 vecRnew = vecR * tapeSize / std::sqrt(CGAL::to_double(vecR.squared_length()));
		if ((vecR.squared_length()-OVERLAP_DIST_THRESHOLD) > vecRnew.squared_length())
			hullPoints.push_back(pnt+vecRnew);						// Add svertex neighbourhood point (tapesize away from vertex)
		else
			hullPoints.push_back(svcIt->target()->point());
	}
Exemplo n.º 4
0
//compute the cross point
Point_3 compute_cross_point(Plane_3 plane, Point_3 start, Point_3 end)
{
	Vector_3 normal = plane.orthogonal_vector();
	Vector_3 line_direction = end - start;
	Point_3  p= plane.point();
	double t;
	double a = (start.x() - p.x()) * normal.x() + (start.y() - p.y()) * normal.y() + (start.z() - p.z()) * normal.z();
	double b = line_direction.x() * normal.x() + line_direction.y() * normal.y() + line_direction.z() * normal.z();

	assert(b != 0);
	t = -a / b;

	return start + t * line_direction;
}
Exemplo n.º 5
0
/**
 * True if u is steeper than v. Uses the square of slope to avoid sqrt.
 */
bool is_steeper(Vector_3 u, Vector_3 v)
{
    Vector_2 u_2 = Vector_2(u.x(), u.y());
    Vector_2 v_2 = Vector_2(v.x(), v.y());
    return ((u.z() * u.z() / u_2.squared_length()) > 
            (v.z() * v.z() / v_2.squared_length())); 
}
Exemplo n.º 6
0
// Assign either ceiling, floor or the default semantic based on input booleans and normal vector
void assignCeilVloor(std::set<Polyhedron::Facet_handle>& fhSet, bool canBeUp, bool canBeDown) {
	pointVector facetPoints;
	Vector_3 ortVec;
	for (std::set<Polyhedron::Facet_handle>::iterator sfIt=fhSet.begin();sfIt!=fhSet.end();++sfIt) {
		if (!canBeUp && !canBeDown) {
			(*sfIt)->semanticBLA = DEFAULT_HOR_SEMANTIC; continue;
		}

		facetPoints = comp_facetPoints(*sfIt);
		CGAL::normal_vector_newell_3(facetPoints.begin(),facetPoints.end(),ortVec);
		if (!normalizeVector(ortVec)) continue;
		if (canBeDown && ortVec.z() <= -HORIZONTAL_ANGLE_RANGE )	(*sfIt)->semanticBLA = DEFAULT_DOWN_SEMANTIC;
		else if (canBeUp && ortVec.z() >= HORIZONTAL_ANGLE_RANGE )	(*sfIt)->semanticBLA = DEFAULT_UP_SEMANTIC;
		else														(*sfIt)->semanticBLA = DEFAULT_HOR_SEMANTIC;
	}
}
Exemplo n.º 7
0
int PlasmaBunch::interaction(int m, int sum){
 register int i, j,k;
 static Vector_3 r;

 int ret=Plasma::interaction(m,sum);

 // now interacting with bunch particles
 int type=0; // ion-ion
 double dEcoul,dEpotent,dQuant;
 double df;

 for(i=0;i<(m<0 ? n : m+1);i++){

   if(i>=ni)type|=0x1;// setting electron-? interaction type
   else type&=0x2;// setting ion-? interaction type
   if(is_ion)type&=0x1;         // setting ?-ion interaction type
   else  type|=0x2;// setting ?-electron interaction type

   for(j=0;j<nb;j++){

     for(k=0;k<3;k++){ // determining the closest
                       //distance and correspondent direction
       r[k]=xx[i][k]-xb[j][k];
       if(r[k]>L/2)r[k]-=L;
       if(r[k]<-L/2)r[k]+=L;
     }

     double R=r.norm();
     if(R<1e-20)printf("Got small distance to bunch (%d,b%d) !\n",i,j);
     r/=R;

     dEcoul=qb/R;

     df=potential(type,R,dEpotent,dQuant);

     for(k=0;k<3;k++){ // to avoid vector copying
       f[i][k]+=df*r[k];
       //f[j][k]-=df*r[k];
     }
     Ecoul+=dEcoul;
     Quant+=dQuant;
     Epotent+=dEpotent;
   }

 }
 return ret;
}
Exemplo n.º 8
0
void Viewer::alphaChanged()
{

    normals.resize(0);
    pos_poly.resize(0);

    std::list<Facet> facets;
    scene->alpha_shape.get_alpha_shape_facets(std::back_inserter(facets), Alpha_shape_3::REGULAR);

    for(std::list<Facet>::iterator fit = facets.begin();
        fit != facets.end();
        ++fit) {
      const Cell_handle& ch = fit->first;
      const int index = fit->second;

      //const Vector_3& n = ch->normal(index); // must be unit vector

      const Point_3& a = ch->vertex((index+1)&3)->point();
      const Point_3& b = ch->vertex((index+2)&3)->point();
      const Point_3& c = ch->vertex((index+3)&3)->point();

      Vector_3 v = CGAL::unit_normal(a,b,c);

      normals.push_back(v.x()); normals.push_back(v.y()); normals.push_back(v.z());
      normals.push_back(v.x()); normals.push_back(v.y()); normals.push_back(v.z());
      normals.push_back(v.x()); normals.push_back(v.y()); normals.push_back(v.z());
      pos_poly.push_back(a.x()); pos_poly.push_back(a.y()); pos_poly.push_back(a.z());
      pos_poly.push_back(b.x()); pos_poly.push_back(b.y()); pos_poly.push_back(b.z());
      pos_poly.push_back(c.x()); pos_poly.push_back(c.y()); pos_poly.push_back(c.z());

    }

    initialize_buffers();

}
static std::vector<Point_3> mapPointsFromOXYplane(std::vector<Point_2> points,
		Vector_3 nu)
{
	DEBUG_START;

	ASSERT(!!Vector3d(nu.x(), nu.y(), nu.z()) && "nu is null vector");

	Vector_3 ez(0., 0, 1.);
	double length = sqrt(nu.squared_length());
	ASSERT(std::fpclassify(length) != FP_ZERO);
	nu = nu * 1. / length; /* Normalize std::vector \nu. */
	ASSERT(std::isfinite(nu.x()));
	ASSERT(std::isfinite(nu.y()));
	ASSERT(std::isfinite(nu.z()));
	Vector_3 tau = cross_product(nu, ez);

	std::vector<Point_3> pointsMapped;
	CGAL::Origin o;
	for (auto &point : points)
	{
		pointsMapped.push_back(o + tau * point.x() + ez * point.y());
	}
	DEBUG_END;
	return pointsMapped;
}
Exemplo n.º 10
0
// Réalise un impact sur la face fs à partir d'une liste de points à déplacer, répartis par couronne (pts[0] = première couronne intérieure, pts[0][0] = premier point de la première couronne)
void DegradeAnObject::impactTheFacetArea(std::vector< std::vector<Point_3> > pts, Facet fs, double ray, int index) {
	double str = 0.02;
	Vector_3 normal = normalizeVector(getNormalOfFacet(fs));
	Kernel::Plane_3 pl(fs.halfedge()->vertex()->point(), normal);
	for(int i = 0 ; i < pts.size() ; i++) {
		for(int j = 0 ; j < pts[i].size() ; j++) {
			bool chk = false;
			Point_iterator pi = polys[index].points_begin();
			while(!chk) {
				++pi;
				if(*pi == pts[i][j]) {
					*pi = Point_3(pi->x() - (impactStrengh(str, i))*normal.x(), pi->y() - (impactStrengh(str, i))*normal.y(), pi->z() - (impactStrengh(str, i))*normal.z());
					chk = true;
				}
			}
		}
	}
}
static Vector_3 leastSquaresPoint(const std::vector<unsigned> activeGroup,
		const std::vector<SupportItem> &items)
{
	DEBUG_START;
	Eigen::Matrix3d matrix;
	Eigen::Vector3d vector;
	for (unsigned i = 0; i < 3; ++i)
	{
		vector(i) = 0.;
		for (unsigned j = 0; j < 3; ++j)
			matrix(i, j) = 0.;
	}

	std::cout << "Calculating least squares points for the following items"
		<< std::endl;
	for (unsigned iPlane : activeGroup)
	{
		SupportItem item = items[iPlane];
		Vector_3 u = item.direction;
		double value = item.value;
		std::cout << "  Item #" << iPlane << ": u = " << u << "; h = "
			<< value << std::endl;
		for (unsigned i = 0; i < 3; ++i)
		{
			for (unsigned j = 0; j < 3; ++j)
				matrix(i, j) += u.cartesian(i)
					* u.cartesian(j);
			vector(i) += u.cartesian(i) * value;
		}
	}
	Eigen::Vector3d solution = matrix.inverse() * vector;

	Vector_3 result(solution(0), solution(1), solution(2));
	std::cout << "Result: " << result << std::endl;
	for (unsigned iPlane : activeGroup)
	{
		SupportItem item = items[iPlane];
		double delta = item.direction * result - item.value;
		std::cout << "  delta = " << delta << std::endl;
	}
	DEBUG_END;
	return result;
}
void buildFacets(Polyhedron_3 polyhedron,
		std::vector<SimpleEdge_3> &edges,
		std::vector<Vector_3> &U, std::vector<double> &H,
		std::map<int, int> &indices)
{
	DEBUG_START;
	std::vector<Plane_3> planes = renumerateFacets(polyhedron, edges,
			indices);
	for (const Plane_3 &plane : planes)
	{
		Vector_3 norm = plane.orthogonal_vector();
		double length = sqrt(norm.squared_length());
		norm = norm * (1. / length);
		double value = -plane.d() / length;
		ASSERT(value > 0.);
		U.push_back(norm);
		H.push_back(value);
	}
	DEBUG_END;
}
Exemplo n.º 13
0
// Computes the intersection C+uV of the planes M*x+D=0 and N*x+E=0.
// Returns -1 if there are no intersections (parallel), 0 for a line
// intersection and 1 for co-planarity.
// precondition: A, B are normalized (hessian form)
int plane_plane_intersection(const Vector_3& M, const double D,
                             const Vector_3& N, const double E,
                             Point_3& C, Vector_3& V)
{
  typedef CGAL::Cartesian<double> K;
  typedef CGAL::Plane_3<K> Plane_3;
  typedef CGAL::Line_3<K> Line_3;

  Plane_3 P1(M.x(), M.y(), M.z(), D);
  Plane_3 P2(N.x(), N.y(), N.z(), E);
  CGAL::Object result = CGAL::intersection(P1, P2);
  if (const Line_3 *iline = CGAL::object_cast<Line_3>(&result)) {
    CGAL::Point_3<K> p = iline->point(0);
    CGAL::Vector_3<K> v = iline->to_vector();
    C = Point_3(p.x(), p.y(), p.z());
    V = Vector_3(v.x(), v.y(), v.z());
    return 0;
  } 
  else if (const Plane_3 *iplane = CGAL::object_cast<Plane_3>(&result)) {
    return 1;
  } 
  else {
    return -1;
  }
}
Exemplo n.º 14
0
int line_plane_intersection(const Point_3& B, const Vector_3& M,
                            const Vector_3& N, const double D,
                            Point_3& p)
{
  typedef CGAL::Cartesian<double> K;
  typedef CGAL::Plane_3<K> Plane_3;
  typedef CGAL::Line_3<K> Line_3;

  CGAL::Point_3<K> CB(B.x(), B.y(), B.z());
  CGAL::Vector_3<K> CM(M.x(), M.y(), M.z());

  Line_3 L(CB, CM);
  Plane_3 P(N.x(), N.y(), N.z(), D);
  CGAL::Object result = CGAL::intersection(L, P);
  if (const CGAL::Point_3<K> *ipoint = CGAL::object_cast<CGAL::Point_3<K> >(&result)) {
    p = Point_3(ipoint->x(), ipoint->y(), ipoint->z());
    return 0;
  } 
  else if (const Line_3 *iline = CGAL::object_cast<Line_3>(&result)) {
    return 1;
  } 
  else {
    return -1;
  }
}
Polyhedron_3 obtainPolyhedron(Polyhedron_3 initialP, std::map<int, int> map,
		IpoptTopologicalCorrector *FTNLP)
{
	DEBUG_START;
	std::vector<Vector_3> directions = FTNLP->getDirections();
	std::vector<double> values = FTNLP->getValues();
	std::vector<Plane_3> planes(initialP.size_of_facets());
	unsigned iFacet = 0;
	for (auto I = initialP.facets_begin(), E = initialP.facets_end();
			I != E; ++I)
	{
		auto it = map.find(iFacet);
		if (it != map.end())
		{
			int i = it->second;
			Vector_3 u = directions[i];
			double h = values[i];
			ASSERT(h > 0);
			planes[iFacet] = Plane_3(-u.x(), -u.y(), -u.z(), h);
			std::cout << "Changing plane #" << iFacet << ": "
				<< I->plane() << " |--> " << planes[iFacet]
				<< std::endl;
		}
		else
		{
			planes[iFacet] = I->plane();
		}
		++iFacet;
	}

	Polyhedron_3 intersection(planes);
	std::cout << "Change in facets number: " << initialP.size_of_facets()
		<< " -> " << intersection.size_of_facets() << std::endl;
	ASSERT(initialP.size_of_facets() - intersection.size_of_facets()
			< map.size() &&
			"It seems that all extracted facets have gone");
	DEBUG_END;
	return intersection;
}
void buildMainTopology(std::vector<SimpleEdge_3> &edges,
		std::vector<Vector_3> &u,
		std::vector<double> &h, std::vector<Vector_3> &points,
		FixedTopology *FT)
{
	DEBUG_START;
	unsigned iTangient = 0;
	for (unsigned i = 0; i < edges.size(); ++i)
	{
		Vector_3 A = edges[i].A;
		Vector_3 B = edges[i].B;
		for (const Plane_3 plane : edges[i].tangients)
		{
			Vector_3 norm = plane.orthogonal_vector();
			double length = sqrt(norm.squared_length());
			norm = norm * (1. / length);
			double value = -plane.d() / length;
			ASSERT(value > 0.);
			u.push_back(norm);
			h.push_back(value);

			if (norm * A > norm * B)
				FT->tangient[2 * i].insert(iTangient);
			else
				FT->tangient[2 * i + 1].insert(iTangient);
			++iTangient;
		}

		FT->incident[edges[i].iForward].insert(2 * i);
		FT->incident[edges[i].iForward].insert(2 * i + 1);
		FT->incident[edges[i].iBackward].insert(2 * i);
		FT->incident[edges[i].iBackward].insert(2 * i + 1);
		points.push_back(A);
		points.push_back(B);
	}
	ASSERT(iTangient > 0);
	DEBUG_END;
}
Point_3 vec_to_point(const Vector_3& v)
{
    return Point_3(v.x(),v.y(),v.z());
}
IGL_INLINE bool igl::copyleft::cgal::segment_segment_squared_distance(
    const CGAL::Segment_3<Kernel> & S1,
    const CGAL::Segment_3<Kernel> & S2,
    CGAL::Point_3<Kernel> & P1,
    CGAL::Point_3<Kernel> & P2,
    typename Kernel::FT & dst)
{
  typedef CGAL::Point_3<Kernel> Point_3;
  typedef CGAL::Vector_3<Kernel> Vector_3;
  typedef typename Kernel::FT EScalar;
  if(S1.is_degenerate())
  {
    // All points on S1 are the same
    P1 = S1.source();
    point_segment_squared_distance(P1,S2,P2,dst);
    return true;
  }else if(S2.is_degenerate())
  {
    assert(!S1.is_degenerate());
    // All points on S2 are the same
    P2 = S2.source();
    point_segment_squared_distance(P2,S1,P1,dst);
    return true;
  }

  assert(!S1.is_degenerate());
  assert(!S2.is_degenerate());

  Vector_3 u = S1.target() - S1.source();
  Vector_3 v = S2.target() - S2.source();
  Vector_3 w = S1.source() - S2.source();

  const auto a = u.dot(u);         // always >= 0
  const auto b = u.dot(v);
  const auto c = v.dot(v);         // always >= 0
  const auto d = u.dot(w);
  const auto e = v.dot(w);
  const auto D = a*c - b*b;        // always >= 0
  assert(D>=0);
  const auto sc=D, sN=D, sD = D;       // sc = sN / sD, default sD = D >= 0
  const auto tc=D, tN=D, tD = D;       // tc = tN / tD, default tD = D >= 0

  bool parallel = false;
  // compute the line parameters of the two closest points
  if (D==0) 
  { 
    // the lines are almost parallel
    parallel = true;
    sN = 0.0;         // force using source point on segment S1
    sD = 1.0;         // to prevent possible division by 0.0 later
    tN = e;
    tD = c;
  } else
  {
    // get the closest points on the infinite lines
    sN = (b*e - c*d);
    tN = (a*e - b*d);
    if (sN < 0.0) 
    { 
      // sc < 0 => the s=0 edge is visible
      sN = 0.0;
      tN = e;
      tD = c;
    } else if (sN > sD) 
    {  // sc > 1  => the s=1 edge is visible
      sN = sD;
      tN = e + b;
      tD = c;
    }
  }

  if (tN < 0.0) 
  {
    // tc < 0 => the t=0 edge is visible
    tN = 0.0;
    // recompute sc for this edge
    if (-d < 0.0)
    {
      sN = 0.0;
    }else if (-d > a)
    {
      sN = sD;
    }else 
    {
      sN = -d;
      sD = a;
    }
  }else if (tN > tD) 
  {
    // tc > 1  => the t=1 edge is visible
    tN = tD;
    // recompute sc for this edge
    if ((-d + b) < 0.0)
    {
      sN = 0;
    }else if ((-d + b) > a)
    {
      sN = sD;
    }else
    {
      sN = (-d +  b);
      sD = a;
    }
  }
  // finally do the division to get sc and tc
  sc = (abs(sN) == 0 ? 0.0 : sN / sD);
  tc = (abs(tN) == 0 ? 0.0 : tN / tD);

  // get the difference of the two closest points
  P1 = S1.source() + sc*(S1.target()-S1.source());
  P2 = S2.source() + sc*(S2.target()-S2.source());
  Vector_3   dP = w + (sc * u) - (tc * v);  // =  S1(sc) - S2(tc)
  assert(dP == (P1-P2));

  dst = dP.squared_length();   // return the closest distance
  return parallel;
}
Exemplo n.º 19
0
void Viewer::drawEdge(const Point_3& from, const Point_3& to, const QColor& clr, float r)
{
  /* Draw regular lines */
  if( m_isFlat ) {
    // disable lighting
    ::glDisable( GL_LIGHTING );

    ::glLineWidth(1.0);
  	qglColor( clr );

    ::glBegin(GL_LINES);
    ::glVertex3f( from.x(), from.y(), from.z() );
    ::glVertex3f( to.x(), to.y(), to.z() );
    ::glEnd();

    // resume lighting
    ::glEnable( GL_LIGHTING );

    return;
  }

  /* Draw edges as 3D cylinders */
  GLboolean lighting, colorMaterial;
  ::glGetBooleanv( GL_LIGHTING, &lighting );
  ::glGetBooleanv( GL_COLOR_MATERIAL, &colorMaterial );
  ::glEnable( GL_LIGHTING );
  ::glDisable(GL_COLOR_MATERIAL);

  float color[4];
  color[0] = clr.redF();
  color[1] = clr.greenF();
  color[2] = clr.blueF();
  color[3] = clr.alphaF();

  Vector_3 v = to - from;

  // compute the length of the edge
  // method 1:
//  float length = sqrt( CGAL::squared_distance( from, to ) );
  // method 2:
  float length = sqrt( v.squared_length() );

  // normalize
  v = v / length;
  // compute the angle: cos theta = v.z/1.0
  GLfloat angle = acos( v.z() ) / 3.1415927 * 180;

  ::glPushMatrix();

  // move to "from" point
  ::glTranslatef( from.x(), from.y(), from.z() );
  // rotate from z-axis to from-->to
  //  axis: cross product of z-axis and from-->to
  ::glRotatef( angle, -v.y(), v.x(), 0.0f );
  // draw
  GLUquadricObj* quadratic = ::gluNewQuadric();	// Create A Pointer To The Quadric Object
  ::gluQuadricNormals( quadratic, GLU_SMOOTH );	// Create Smooth Normals
  ::glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color );
  // gluCylinder draws a cylinder oriented along the z-axis
  ::gluCylinder( quadratic, r, r, length, 16, 4 );

  // move back to origin
  ::glPopMatrix();

  if ( colorMaterial )
    ::glEnable( GL_COLOR_MATERIAL );
  if ( !lighting )
    ::glDisable( GL_LIGHTING );
}
Exemplo n.º 20
0
/******************************************************************************
* Creates the geometry for a single arrow element.
******************************************************************************/
void OpenGLArrowPrimitive::createArrowElement(int index, const Point3& pos, const Vector3& dir, const ColorA& color, FloatType width)
{
	const float arrowHeadRadius = width * 2.5f;
	const float arrowHeadLength = arrowHeadRadius * 1.8f;

	if(shadingMode() == NormalShading) {

		// Build local coordinate system.
		Vector_3<float> t, u, v;
		float length = dir.length();
		if(length != 0) {
			t = dir / length;
			if(dir.y() != 0 || dir.x() != 0)
				u = Vector_3<float>(dir.y(), -dir.x(), 0);
			else
				u = Vector_3<float>(-dir.z(), 0, dir.x());
			u.normalize();
			v = u.cross(t);
		}
		else {
			t.setZero();
			u.setZero();
			v.setZero();
		}

		ColorAT<float> c = color;
		Point_3<float> v1 = pos;
		Point_3<float> v2;
		Point_3<float> v3 = v1 + dir;
		float r;
		if(length > arrowHeadLength) {
			v2 = v1 + t * (length - arrowHeadLength);
			r = arrowHeadRadius;
		}
		else {
			v2 = v1;
			r = arrowHeadRadius * length / arrowHeadLength;
		}

		OVITO_ASSERT(_mappedVerticesWithNormals);
		VertexWithNormal* vertex = _mappedVerticesWithNormals + (index * _verticesPerElement);

		// Generate vertices for cylinder.
		for(int i = 0; i <= _cylinderSegments; i++) {
			Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
			Vector_3<float> d = n * width;
			vertex->pos = v1 + d;
			vertex->normal = n;
			vertex->color = c;
			vertex++;
			vertex->pos = v2 + d;
			vertex->normal = n;
			vertex->color = c;
			vertex++;
		}

		// Generate vertices for head cone.
		for(int i = 0; i <= _cylinderSegments; i++) {
			Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
			Vector_3<float> d = n * r;
			vertex->pos = v2 + d;
			vertex->normal = n;
			vertex->color = c;
			vertex++;
			vertex->pos = v3;
			vertex->normal = n;
			vertex->color = c;
			vertex++;
		}

		// Generate vertices for cylinder cap.
		for(int i = 0; i < _cylinderSegments; i++) {
			Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
			Vector_3<float> d = n * width;
			vertex->pos = v1 + d;
			vertex->normal = Vector_3<float>(0,0,-1);
			vertex->color = c;
			vertex++;
		}

		// Generate vertices for cone cap.
		for(int i = 0; i < _cylinderSegments; i++) {
			Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
			Vector_3<float> d = n * r;
			vertex->pos = v2 + d;
			vertex->normal = Vector_3<float>(0,0,-1);
			vertex->color = c;
			vertex++;
		}
	}
	else if(shadingMode() == FlatShading) {

		Vector_3<float> t;
		float length = dir.length();
		if(length != 0)
			t = dir / length;
		else
			t.setZero();

		ColorAT<float> c = color;
		Point_3<float> base = pos;

		OVITO_ASSERT(_mappedVerticesWithElementInfo);
		VertexWithElementInfo* vertices = _mappedVerticesWithElementInfo + (index * _verticesPerElement);

		if(length > arrowHeadLength) {
			vertices[0].pos = Point_3<float>(length, 0, 0);
			vertices[1].pos = Point_3<float>(length - arrowHeadLength, arrowHeadRadius, 0);
			vertices[2].pos = Point_3<float>(length - arrowHeadLength, width, 0);
			vertices[3].pos = Point_3<float>(0, width, 0);
			vertices[4].pos = Point_3<float>(0, -width, 0);
			vertices[5].pos = Point_3<float>(length - arrowHeadLength, -width, 0);
			vertices[6].pos = Point_3<float>(length - arrowHeadLength, -arrowHeadRadius, 0);
		}
		else {
			float r = arrowHeadRadius * length / arrowHeadLength;
			vertices[0].pos = Point_3<float>(length, 0, 0);
			vertices[1].pos = Point_3<float>(0, r, 0);
			vertices[2].pos = Point_3<float>::Origin();
			vertices[3].pos = Point_3<float>::Origin();
			vertices[4].pos = Point_3<float>::Origin();
			vertices[5].pos = Point_3<float>::Origin();
			vertices[6].pos = Point_3<float>(0, -r, 0);
		}
		for(int i = 0; i < _verticesPerElement; i++, ++vertices) {
			vertices->base = base;
			vertices->dir = t;
			vertices->color = c;
		}
	}
}
Exemplo n.º 21
0
/******************************************************************************
* Creates the geometry for a single cylinder element.
******************************************************************************/
void OpenGLArrowPrimitive::createCylinderElement(int index, const Point3& pos, const Vector3& dir, const ColorA& color, FloatType width)
{
	if(_usingGeometryShader && (shadingMode() == FlatShading || renderingQuality() == HighQuality)) {
		OVITO_ASSERT(_mappedVerticesWithElementInfo);
		OVITO_ASSERT(_verticesPerElement == 1);
		VertexWithElementInfo* vertex = _mappedVerticesWithElementInfo + index;
		vertex->pos = vertex->base = pos;
		vertex->dir = dir;
		vertex->color = color;
		vertex->radius = width;
		return;
	}

	if(shadingMode() == NormalShading) {

		// Build local coordinate system.
		Vector_3<float> t, u, v;
		float length = dir.length();
		if(length != 0) {
			t = dir / length;
			if(dir.y() != 0 || dir.x() != 0)
				u = Vector_3<float>(dir.y(), -dir.x(), 0);
			else
				u = Vector_3<float>(-dir.z(), 0, dir.x());
			u.normalize();
			v = u.cross(t);
		}
		else {
			t.setZero();
			u.setZero();
			v.setZero();
		}

		ColorAT<float> c = color;
		Point_3<float> v1 = pos;
		Point_3<float> v2 = v1 + dir;

		if(renderingQuality() != HighQuality) {
			OVITO_ASSERT(_mappedVerticesWithNormals);
			VertexWithNormal* vertex = _mappedVerticesWithNormals + (index * _verticesPerElement);

			// Generate vertices for cylinder mantle.
			for(int i = 0; i <= _cylinderSegments; i++) {
				Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
				Vector_3<float> d = n * width;
				vertex->pos = v1 + d;
				vertex->normal = n;
				vertex->color = c;
				vertex++;
				vertex->pos = v2 + d;
				vertex->normal = n;
				vertex->color = c;
				vertex++;
			}

			// Generate vertices for first cylinder cap.
			for(int i = 0; i < _cylinderSegments; i++) {
				Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
				Vector_3<float> d = n * width;
				vertex->pos = v1 + d;
				vertex->normal = Vector_3<float>(0,0,-1);
				vertex->color = c;
				vertex++;
			}

			// Generate vertices for second cylinder cap.
			for(int i = _cylinderSegments - 1; i >= 0; i--) {
				Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
				Vector_3<float> d = n * width;
				vertex->pos = v2 + d;
				vertex->normal = Vector_3<float>(0,0,1);
				vertex->color = c;
				vertex++;
			}
		}
		else {
			// Create bounding box geometry around cylinder for raytracing.
			OVITO_ASSERT(_mappedVerticesWithElementInfo);
			VertexWithElementInfo* vertex = _mappedVerticesWithElementInfo + (index * _verticesPerElement);
			OVITO_ASSERT(_verticesPerElement == 14);
			u *= width;
			v *= width;
			Point3 corners[8] = {
					v1 - u - v,
					v1 - u + v,
					v1 + u - v,
					v1 + u + v,
					v2 - u - v,
					v2 - u + v,
					v2 + u + v,
					v2 + u - v
			};
			const static size_t stripIndices[14] = { 3,2,6,7,4,2,0,3,1,6,5,4,1,0 };
			for(int i = 0; i < 14; i++, vertex++) {
				vertex->pos = corners[stripIndices[i]];
				vertex->base = v1;
				vertex->dir = dir;
				vertex->color = c;
				vertex->radius = width;
			}
		}
	}
	else if(shadingMode() == FlatShading) {

		Vector_3<float> t;
		float length = dir.length();
		if(length != 0)
			t = dir / length;
		else
			t.setZero();

		ColorAT<float> c = color;
		Point_3<float> base = pos;

		OVITO_ASSERT(_mappedVerticesWithElementInfo);
		VertexWithElementInfo* vertices = _mappedVerticesWithElementInfo + (index * _verticesPerElement);
		vertices[0].pos = Point_3<float>(0, width, 0);
		vertices[1].pos = Point_3<float>(0, -width, 0);
		vertices[2].pos = Point_3<float>(length, -width, 0);
		vertices[3].pos = Point_3<float>(length, width, 0);
		for(int i = 0; i < _verticesPerElement; i++, ++vertices) {
			vertices->base = base;
			vertices->dir = t;
			vertices->color = c;
		}
	}
}
std::array<double,3> convert_to_array(const Vector_3& p)
{
    return std::array<double,3>({p.x(),p.y(),p.z()});
}
Exemplo n.º 23
0
// Génère le vecteur qui a subi une rotation d'angle teta
Vector_3 DegradeAnObject::rotationVector(Vector_3 v, Vector_3 normal, double teta) {
	double c = cos(teta);
	double s = sin(teta);
	Kernel::RT m00 = normal.x() * normal.x() * (1-c) + c;
	Kernel::RT m01 = normal.x() * normal.y() * (1-c) - normal.z() * s;
	Kernel::RT m02 = normal.x() * normal.z() * (1-c) + normal.y() * s;
	Kernel::RT m10 = normal.x() * normal.y() * (1-c) + normal.z() * s;
	Kernel::RT m11 = normal.y() * normal.y() * (1-c) + c;
	Kernel::RT m12 = normal.z() * normal.y() * (1-c) - normal.x() * s;
	Kernel::RT m20 = normal.x() * normal.z() * (1-c) - normal.y() * s;
	Kernel::RT m21 = normal.z() * normal.y() * (1-c) + normal.x() * s;
	Kernel::RT m22 = normal.z() * normal.z() * (1-c) + c;
	CGAL::Aff_transformation_3<Kernel> rotate(m00, m01, m02, m10, m11, m12, m20, m21, m22);
	return rotate.transform(v);
}
Exemplo n.º 24
0
void apply_semanticRequirements(Polyhedron& exteriorPolyhe) {
	std::map<std::string,std::vector<bool>> semanticNormals;
	semanticNormals["Roof"] = std::vector<bool>(3,true);
	semanticNormals["Roof"][2] = false;		// down
	semanticNormals["Ground"] = std::vector<bool>(3,false);
	semanticNormals["Ground"][2] = true;
	semanticNormals["Ceiling"] = std::vector<bool>(3,false);
	semanticNormals["Ceiling"][2] = true;
	semanticNormals["Floor"] = std::vector<bool>(3,false);
	semanticNormals["Floor"][0] = true;
	semanticNormals["Wall"] = std::vector<bool>(3,true);
	semanticNormals["Window"] = std::vector<bool>(3,true);
	semanticNormals["Door"] = std::vector<bool>(3,true);
	semanticNormals["Closure"] = std::vector<bool>(3,true);
	semanticNormals[TO_DIST_SEMANTIC] = std::vector<bool>(3,true);
	//semanticNormals["Anything"] = std::vector<bool>(3,true);

	std::map<std::string,int> semanticEnum;
	semanticEnum["Roof"]		= 1;
	semanticEnum["Window"]		= 2;
	semanticEnum["Door"]		= 3;
	semanticEnum["Wall"]		= 4;
	semanticEnum["Ground"]		= 5;
	semanticEnum["Ceiling"]		= 6;
	semanticEnum["Floor"]		= 7;
	semanticEnum["Closure"]		= 8;

	semanticEnum["Anything"]	= 9;
	//semanticEnum["Install"]		= 10;
	
	Vector_3 ortVec;
	
	Polyhedron::Facet_iterator exfIt;						// Iterate over exterior faces
	for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) {	
			
		int minSem = 99;
			
		for (std::vector<std::string>::iterator svIt=exfIt->equidistSems.begin();svIt!=exfIt->equidistSems.end();++svIt) {				// Add equidist semantics
			std::map<std::string,int>::iterator seIt = semanticEnum.find(*svIt);
			if (seIt!=semanticEnum.end()) {				// ......
				if (seIt->second<minSem) {
					minSem = seIt->second;
					exfIt->semanticBLA = *svIt;
				}
			}else {										// This seems wrong...
				exfIt->semanticBLA = *svIt;
				break;
			}
		}

		pointVector facetPoints = comp_facetPoints(exfIt);
		CGAL::normal_vector_newell_3(facetPoints.begin(),facetPoints.end(),ortVec); // Calculate normal vector, ortVec set to zero in newell
		if (!normalizeVector(ortVec)) continue;

		std::map<std::string,std::vector<bool>>::iterator  snIt = semanticNormals.find(exfIt->semanticBLA);
		if (snIt!=semanticNormals.end()) {
			if		(!snIt->second[0] && ortVec.z() > HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_UP_SEMANTIC;
			else if (!snIt->second[1] && ortVec.z() <= HORIZONTAL_ANGLE_RANGE && ortVec.z() >= -HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_HOR_SEMANTIC;
			else if (!snIt->second[2] && ortVec.z() <= -HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_DOWN_SEMANTIC;
		} else {
			if		(ortVec.z() > HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_UP_SEMANTIC;
			else if (ortVec.z() <= HORIZONTAL_ANGLE_RANGE && ortVec.z() >= -HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_HOR_SEMANTIC;
			else if (ortVec.z() <= -HORIZONTAL_ANGLE_RANGE)
				exfIt->semanticBLA = DEFAULT_DOWN_SEMANTIC;
		}
	}
	// Set semantics of facets created due to closing (too far from original geometry)
	for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) {	
		if (exfIt->semanticBLA==TO_DIST_SEMANTIC) {
			std::set<Polyhedron::Facet_handle> fhSet;
			connectedSemFacets(exfIt,TO_DIST_SEMANTIC,false,fhSet);
			bool canBeUp	= indirectlyTouchingFindSem(DEFAULT_UP_SEMANTIC,fhSet);
			bool canBeDown	= indirectlyTouchingFindSem(DEFAULT_DOWN_SEMANTIC,fhSet);
			assignCeilVloor(fhSet,canBeUp,canBeDown);
		}
	}
}
Exemplo n.º 25
0
// Normalise un vecteur
Vector_3 DegradeAnObject::normalizeVector(Vector_3 v) {
	double norm = sqrt(to_double(v.x() * v.x() + v.y() * v.y() + v.z() * v.z()));
	return v/norm;
}
Exemplo n.º 26
0
Point_3 Origin::operator-(const Vector_3& v) const {return Point_3( CGAL::ORIGIN-v.get_data() ); }
Exemplo n.º 27
0
int Plasma::interaction(int m, int sum){
 register int i, j,k;
 static Vector_3 r;
 //static Vector_3 df;
 int type=0; // ion-ion

 for(i=(m<0 ? 0 : m);i<n;i++){
   for(k=0;k<3;k++){
     f[i][k]=0;   // reducing to elementary cell

     if(x[i][k]>0)xx[i][k]=amod1(x[i][k]+L/2,L)-L/2;
     else xx[i][k]=amod1(x[i][k]-L/2,L)+L/2;

   }
   if(m>=0)break;
 }


 Quant=Ecoul=0;
 double dEcoul,dEpotent,dQuant;
 double df;

 if(!is_matr || m<0)Epotent=0;


 for(i=0;i<(m<0 ? n : m+1);i++){

   if(i>=ni)type|=0x1;// setting electron-? interaction type
   type&=0x1;         // setting ?-ion interaction type

   for(j=((m<0 || i==m) ? i+1: m); j<n;j++){
    if(j>=ni)type|=0x2;// setting ?-electron interaction type
    //r=xx[i]-xx[j];

    for(k=0;k<3;k++){ // determining the closest
                      //distance and correspondent direction

      r[k]=xx[i][k]-xx[j][k];
      if(r[k]>L/2)r[k]-=L;
      if(r[k]<-L/2)r[k]+=L;
    }

    double R=r.norm();

    if(R<1e-20){
      printf("Got small distance (%d,%d) !\n",i,j);
    }
    r/=R;

    dEcoul=-1/R;
    if(type==ELCELC || type ==IONION){
      dEcoul=-dEcoul;
      if(write_distr){
	if(non_symm && type==IONION)DRRpp.point(R,1.);
	else DRRee.point(R,1.);
      }
    }
    else if(write_distr)DRRep.point(R,1.);

    df=potential(type,R,dEpotent,dQuant);
    ///df=PotentialKELBG(type,R,dEpotent,dQuant);


    //f[i]+=df;
    //f[j]-=df;

    for(k=0;k<3;k++){ // to avoid vector copying
      f[i][k]+=df*r[k];
      f[j][k]-=df*r[k];
    }

    Ecoul+=dEcoul;

    Quant+=dQuant;


    if(is_matr && m>=0)Epotent+=dEpotent-(*umatr)(i,j);
    else Epotent+=dEpotent;

    if(is_matr){
      if(m>=0){
	int l=(i< m ? i : j);
	(*umatr)(l,l)=(*umatr)(i,j); //(l,l) used for storing temporary
	//fucktmp[l]=(*umatr)(i,j);
	//printf("%d <- (%d, %d)[%f]\n",l,i,j,fucktmp[l]);
      }
      (*umatr)(i,j)=dEpotent;
    }

    if(m>=0 && i!=m)break;

   }

 }

 if(is_matr && m>=0 && sum){
   Epotent=0;
   for(i=0;i<n;i++){
     for(j=i+1;j<n;j++){
       Epotent+=(*umatr)(i,j);
     }
   }
 }

 return 0;
}
Exemplo n.º 28
0
// Convert elemental values to nodal values.
void Window_manifold_2::
elements_to_nodes( const COM::DataItem *e_vals, 
		   COM::DataItem *n_vals, 
		   const int scheme,
		   const COM::DataItem *e_weights,
		   COM::DataItem *n_weights,
		   const int tosum) {
  COM_assertion_msg( e_vals && e_vals->is_elemental(),
		     "First argument must be elemental dataitem");
  COM_assertion_msg( n_vals && n_vals->is_nodal(),
		     "Second argument must be nodal dataitem");
  COM_assertion_msg( scheme!=E2N_USER || 
		     e_weights && e_weights->is_elemental(),
		     "Third argument must be elemental dataitem");
  COM_assertion_msg( !n_weights || n_weights->is_nodal() && 
		     COM_compatible_types(COM_DOUBLE, n_weights->data_type()),
		     "Output weights must be nodal with double precision");

  // Inherit nodal and elemental values onto the window
  COM::DataItem *nodal_vals;
  if ( n_vals->window() != _buf_window)
    nodal_vals = _buf_window->inherit( n_vals, "nodal_vals__E2NTEMP", 
				       false, true, NULL, 0);
  else 
    nodal_vals = n_vals;

  const COM::DataItem *elem_vals;
  if ( e_vals->window() != _buf_window)
    elem_vals = _buf_window->inherit
      ( const_cast<COM::DataItem*>(e_vals), "elem_vals__E2NTEMP", 
	false, true, NULL, 0);
  else
    elem_vals = e_vals;

  // Inherit nodal and elemental weights onto the window
  COM::DataItem *nodal_weights; 
  if ( n_weights && n_weights->window()!=_buf_window) 
    nodal_weights = _buf_window->inherit( n_weights, "nodal_weights__E2NTEMP", 
					  false, true, NULL, 0);
  else {
    nodal_weights = _buf_window->new_dataitem( "nodal_weights__E2NTEMP", 'n',
						COM_DOUBLE, 1, "");
    _buf_window->resize_array( nodal_weights, NULL);
  }

  const COM::DataItem *elem_weights; 
  if ( e_weights && e_weights->window()!=_buf_window) 
    elem_weights = _buf_window->inherit
      ( const_cast<COM::DataItem*>(e_weights), "elem_weights__E2NTEMP", 
	false, true, NULL, 0);
  else
    elem_weights = e_weights;
  _buf_window->init_done( false);

  // Initialize communicator
  if ( _cc==NULL) init_communicator();
  int local_npanes = _cc->panes().size();

  // Initialize buffer spaces for nodal weights.
  std::vector< Real*> weights_ptrs(local_npanes);
  std::vector< int>   weights_strds(local_npanes);
  
  int ncomp = nodal_vals->size_of_components();
  COM_assertion_msg( elem_vals->size_of_components()==ncomp,
		     "Numbers of components must match");

  for (int i=0; i<local_npanes; ++i) {
    int nn=_cc->panes()[i]->size_of_real_nodes();
    Real *p;
    int  strd;
    COM::DataItem *a = _cc->panes()[i]->dataitem(nodal_weights->id());
    p = weights_ptrs[i] = reinterpret_cast<Real*>(a->pointer());
    strd = weights_strds[i] = a->stride();

    // Initialize values to 0.
    for ( int k=0; k<nn; ++k, p+=strd) *p = 0.;
  }

  Vector_3<Real> J[2];
  Vector_2<Real> nc(0.5,0.5);

  Element_node_vectors_k_const<Point_3<Real> > ps;
  Element_vectors_k_const<Real>                elem_vals_evk;
  Element_node_vectors_k<Real>                 nodal_vals_evk;
  Element_vectors_k_const<Real>                elem_weights_evk;
  Element_node_vectors_k<Real>                 nodal_weights_evk;

  // Compute nodal sums and weights on each processor
  std::vector< COM::Pane*>::const_iterator it=_cc->panes().begin();
  for (int i=0; i<local_npanes; ++i, ++it) { // Loop through the panes
    COM::Pane &pane = **it;

    const Point_3<Real> *pnts = reinterpret_cast<const Point_3<Real>*>
      (pane.coordinates());
    const COM::DataItem *elem_vals_pane = 
      pane.dataitem( elem_vals->id());
    const COM::DataItem *elem_weights_pane = 
      elem_weights ? pane.dataitem( elem_weights->id()) : NULL;
    COM::DataItem *nodal_vals_pane = 
      pane.dataitem( nodal_vals->id());

    // Initialize values of nodal_vals_pane to 0.
    for ( int d=1; d<=ncomp; ++d) {
      COM::DataItem *nvpi = ncomp==1?nodal_vals_pane:(nodal_vals_pane+d);
      Real *p=reinterpret_cast<Real*>(nvpi->pointer());
      for ( int j=0,s=nvpi->stride(),n=nvpi->size_of_real_items()*s; j<n; j+=s)
	p[j] = 0.;
    }

    // Loop through the elements of the pane
    Element_node_enumerator ene( &pane, 1); 
    for ( int j=pane.size_of_real_elements(); j>0; --j, ene.next()) {
      ps.set( pnts, ene, 1);
      elem_vals_evk.set( elem_vals_pane, ene);
      nodal_vals_evk.set( nodal_vals_pane, ene);
      nodal_weights_evk.set( weights_ptrs[i], ene, weights_strds[i]);

      int ne=ene.size_of_edges();
      int nn=ene.size_of_nodes();
      Real w = 1.;
      switch ( scheme) {
      case E2N_USER:
      case E2N_AREA:
	if ( scheme == E2N_USER) {
	  // Use user specified weights.
	  elem_weights_evk.set( elem_weights_pane, ene);
	  w = elem_weights_evk[0];
	} // Continue to the case of E2N_ONE
	else { 
	  Generic_element_2 e(ne, nn);
	  e.Jacobian( ps, nc, J);
	  
	  const Vector_3<Real> v = Vector_3<Real>::cross_product( J[0], J[1]);
	  w = std::sqrt(v.squared_norm());
	  if ( ne==3) w*=0.5;
	}  // Continue to the case of E2N_ONE
      case E2N_ONE: {
	// Update nodal weights
	for ( int k=0; k<nn; ++k)
	  nodal_weights_evk[k] += w;
	
	// Update nodal sums
	for ( int d=0; d<ncomp; ++d) {
	  Real t = w*elem_vals_evk(0,d);
	  for ( int k=0; k<nn; ++k)
	    nodal_vals_evk(k,d) += t;
	}
	break;
      }
      case E2N_ANGLE:
      case E2N_SPHERE: {
	for ( int k=0; k<ne; ++k) { 
	  J[0] = ps[k==ne-1?0:k+1]-ps[k]; J[1] = ps[k?k-1:ne-1]-ps[k]; 
	  double s = std::sqrt((J[0]*J[0])*(J[1]*J[1]));
	  if ( s>0) {
	    double cosw = J[0]*J[1]/s; 
	    if (cosw>1) cosw=1; else if ( cosw<-1) cosw=-1;
	    w = std::acos( cosw);

	    if ( scheme==SURF::E2N_SPHERE)
	      w = std::sin(w)/s; 

	    // Update nodal weights
	    nodal_weights_evk[k] += w;
	    
	    // Update nodal sums
	    for ( int d=0; d<ncomp; ++d)
	      nodal_vals_evk(k,d) += w*elem_vals_evk(0,d);
	  }
	}
	for ( int k=ne; k<nn; ++k) {
	  // Update nodal weights
	  nodal_weights_evk[k] += 1;

	  // Update nodal sums
	  for ( int d=0; d<ncomp; ++d)
	    nodal_vals_evk(k,d) += elem_vals_evk(0,d);
	}
	break;
      }

      default: COM_assertion_msg(false, "Should never reach here");
      }
    }
  }

  // Performan reductions on shared nodes for nodal sums
  reduce_on_shared_nodes( nodal_vals, OP_SUM);

  // Performan reductions on shared nodes for nodal weights
  _cc->init( &(void*&)weights_ptrs[0], COM_DOUBLE, 1, NULL, NULL);
  _cc->begin_update_shared_nodes();
  _cc->reduce_on_shared_nodes( MPI_SUM);
  _cc->end_update_shared_nodes();

  if ( !tosum) {
    // Divide nodal sums by weights on each processor
    it=_cc->panes().begin();
    for (int i=0; i<local_npanes; ++i, ++it) { // Loop through the panes
      COM::Pane &pane = **it;
      COM::DataItem *nodal_vals_pane = pane.dataitem( nodal_vals->id());

      for ( int d=1; d<=ncomp; ++d) {
	COM::DataItem *nvpi = ncomp==1?nodal_vals_pane:(nodal_vals_pane+d);
	Real *v=reinterpret_cast<Real*>(nvpi->pointer());
	Real *w = weights_ptrs[i];
	for ( int j=0,js=nvpi->stride(),n=nvpi->size_of_real_items()*js,
		k=0, ks=weights_strds[i]; j<n; j+=js, k+=ks) {
	  if ( w[k]==0) {
	    std::cout << "***Rocsurf Error: Got zero weight for node " 
		      << j+1 << " in pane " << pane.id() << std::endl;
	  }
	  if ( w[k] == 0) v[j] = 0;
	  else v[j] /= w[k];
	}
      }
    }
  }

  // Delete the temporary dataitems in reverse order.
  if ( elem_weights != e_weights) 
    _buf_window->delete_dataitem( elem_weights->name());
  _buf_window->delete_dataitem( nodal_weights->name());
  if ( elem_vals != e_vals) 
    _buf_window->delete_dataitem( elem_vals->name());
  if (nodal_vals != n_vals) 
    _buf_window->delete_dataitem( nodal_vals->name());
  _buf_window->init_done( false);
}