Exemplo n.º 1
0
static void set_margin(t_atoms *atoms, rvec *x, real *r)
{
  int i,d,start;
  
  box_margin=0;
  
  start=0;
  for(i=0; i < atoms->nr; i++) {
    if ( (i+1 == atoms->nr) || 
	 (atoms->atom[i+1].resnr != atoms->atom[i].resnr) ) {
      d=max_dist(x,r,start,i+1);
      if (debug && d>box_margin)
	fprintf(debug,"getting margin from %s: %g\n",
		*(atoms->resname[atoms->atom[i].resnr]),box_margin);
      box_margin=max(box_margin,d);
      start=i+1;
    }
  }
  fprintf(stderr,"box_margin = %g\n",box_margin);
}
Exemplo n.º 2
0
bool
CurveWarp::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
{
	Point start_point=param_start_point.get(Point());
	Point end_point=param_end_point.get(Point());

	SuperCallback stageone(cb,0,9000,10000);
	SuperCallback stagetwo(cb,9000,10000,10000);

	int x,y;

	const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
	Point tl(renddesc.get_tl());
	Point br(renddesc.get_br());
	const int w(renddesc.get_w());
	const int h(renddesc.get_h());

	// find a bounding rectangle for the context we need to render
	// todo: find a better way of doing this - this way doesn't work
	Rect src_rect(transform(tl));
	Point pos1, pos2;
	Real dist, along;
	Real min_dist(999999), max_dist(-999999), min_along(999999), max_along(-999999);

#define UPDATE_DIST \
	if (dist < min_dist) min_dist = dist; \
	if (dist > max_dist) max_dist = dist; \
	if (along < min_along) min_along = along; \
	if (along > max_along) max_along = along

	// look along the top and bottom edges
	pos1[0] = pos2[0] = tl[0]; pos1[1] = tl[1]; pos2[1] = br[1];
	for (x = 0; x < w; x++, pos1[0] += pw, pos2[0] += pw)
	{
		src_rect.expand(transform(pos1, &dist, &along)); UPDATE_DIST;
		src_rect.expand(transform(pos2, &dist, &along)); UPDATE_DIST;
	}

	// look along the left and right edges
	pos1[0] = tl[0]; pos2[0] = br[0]; pos1[1] = pos2[1] = tl[1];
	for (y = 0; y < h; y++, pos1[1] += ph, pos2[1] += ph)
	{
		src_rect.expand(transform(pos1, &dist, &along)); UPDATE_DIST;
		src_rect.expand(transform(pos2, &dist, &along)); UPDATE_DIST;
	}

	// look along the diagonals
	const int max_wh(std::max(w,h));
	const Real inc_x((br[0]-tl[0])/max_wh),inc_y((br[1]-tl[1])/max_wh);
	pos1[0] = pos2[0] = tl[0]; pos1[1] = tl[1]; pos2[1] = br[1];
	for (x = 0; x < max_wh; x++, pos1[0] += inc_x, pos2[0] = pos1[0], pos1[1]+=inc_y, pos2[1]-=inc_y)
	{
		src_rect.expand(transform(pos1, &dist, &along)); UPDATE_DIST;
		src_rect.expand(transform(pos2, &dist, &along)); UPDATE_DIST;
	}

#if 0
	// look at each blinepoint
	std::vector<synfig::BLinePoint>::const_iterator iter;
	for (iter=bline.begin(); iter!=bline.end(); iter++)
		src_rect.expand(transform(iter->get_vertex()+origin, &dist, &along)); UPDATE_DIST;
#endif

	Point src_tl(src_rect.get_min());
	Point src_br(src_rect.get_max());

	Vector ab((end_point - start_point).norm());
	Angle::tan ab_angle(ab[1], ab[0]);

	Real used_length = max_along - min_along;
	Real render_width = max_dist - min_dist;

	int src_w = (abs(used_length*Angle::cos(ab_angle).get()) +
				 abs(render_width*Angle::sin(ab_angle).get())) / abs(pw);
	int src_h = (abs(used_length*Angle::sin(ab_angle).get()) +
				 abs(render_width*Angle::cos(ab_angle).get())) / abs(ph);

	Real src_pw((src_br[0] - src_tl[0]) / src_w);
	Real src_ph((src_br[1] - src_tl[1]) / src_h);

	if (src_pw > abs(pw))
	{
		src_w = int((src_br[0] - src_tl[0]) / abs(pw));
		src_pw = (src_br[0] - src_tl[0]) / src_w;
	}

	if (src_ph > abs(ph))
	{
		src_h = int((src_br[1] - src_tl[1]) / abs(ph));
		src_ph = (src_br[1] - src_tl[1]) / src_h;
	}

#define MAXPIX 10000
	if (src_w > MAXPIX) src_w = MAXPIX;
	if (src_h > MAXPIX) src_h = MAXPIX;

	// this is an attempt to remove artifacts around tile edges - the
	// cubic interpolation uses at most 2 pixels either side of the
	// target pixel, so add an extra 2 pixels around the tile on all
	// sides
	src_tl -= (Point(src_pw,src_ph)*2);
	src_br += (Point(src_pw,src_ph)*2);
	src_w += 4;
	src_h += 4;
	src_pw = (src_br[0] - src_tl[0]) / src_w;
	src_ph = (src_br[1] - src_tl[1]) / src_h;

	// set up a renddesc for the context to render
	RendDesc src_desc(renddesc);
	src_desc.clear_flags();
	src_desc.set_tl(src_tl);
	src_desc.set_br(src_br);
	src_desc.set_wh(src_w, src_h);

	// render the context onto a new surface
	Surface source;
	source.set_wh(src_w,src_h);
	if(!context.accelerated_render(&source,quality,src_desc,&stageone))
		return false;

	float u,v;
	Point pos, tmp;

	surface->set_wh(w,h);
	surface->clear();

	if(quality<=4)				// CUBIC
		for(y=0,pos[1]=tl[1];y<h;y++,pos[1]+=ph)
		{
			for(x=0,pos[0]=tl[0];x<w;x++,pos[0]+=pw)
			{
				tmp=transform(pos);
				u=(tmp[0]-src_tl[0])/src_pw;
				v=(tmp[1]-src_tl[1])/src_ph;
				if(u<0 || v<0 || u>=src_w || v>=src_h || isnan(u) || isnan(v))
					(*surface)[y][x]=context.get_color(tmp);
				else
					(*surface)[y][x]=source.cubic_sample(u,v);
			}
			if((y&31)==0 && cb && !stagetwo.amount_complete(y,h)) return false;
		}
	else if (quality<=6)		// INTERPOLATION_LINEAR
		for(y=0,pos[1]=tl[1];y<h;y++,pos[1]+=ph)
		{
			for(x=0,pos[0]=tl[0];x<w;x++,pos[0]+=pw)
			{
				tmp=transform(pos);
				u=(tmp[0]-src_tl[0])/src_pw;
				v=(tmp[1]-src_tl[1])/src_ph;
				if(u<0 || v<0 || u>=src_w || v>=src_h || isnan(u) || isnan(v))
					(*surface)[y][x]=context.get_color(tmp);
				else
					(*surface)[y][x]=source.linear_sample(u,v);
			}
			if((y&31)==0 && cb && !stagetwo.amount_complete(y,h)) return false;
		}
	else						// NEAREST_NEIGHBOR
		for(y=0,pos[1]=tl[1];y<h;y++,pos[1]+=ph)
		{
			for(x=0,pos[0]=tl[0];x<w;x++,pos[0]+=pw)
			{
				tmp=transform(pos);
				u=(tmp[0]-src_tl[0])/src_pw;
				v=(tmp[1]-src_tl[1])/src_ph;
				if(u<0 || v<0 || u>=src_w || v>=src_h || isnan(u) || isnan(v))
					(*surface)[y][x]=context.get_color(tmp);
				else
					(*surface)[y][x]=source[floor_to_int(v)][floor_to_int(u)];
			}
			if((y&31)==0 && cb && !stagetwo.amount_complete(y,h)) return false;
		}

	// Mark our progress as finished
	if(cb && !cb->amount_complete(10000,10000))
		return false;

	return true;
}
Exemplo n.º 3
0
bool
CurveWarp::accelerated_cairorender(Context context, cairo_t *cr, int quality, const RendDesc &renddesc_, ProgressCallback *cb)const
{
	Point start_point=param_start_point.get(Point());
	Point end_point=param_end_point.get(Point());

	SuperCallback stageone(cb,0,9000,10000);
	SuperCallback stagetwo(cb,9000,10000,10000);
	
	RendDesc renddesc(renddesc_);
	// Untransform the render desc
	if(!cairo_renddesc_untransform(cr, renddesc))
		return false;
	
	int x,y;
	
	const Real pw(renddesc.get_pw()),ph(renddesc.get_ph());
	Point tl(renddesc.get_tl());
	Point br(renddesc.get_br());
	const int w(renddesc.get_w());
	const int h(renddesc.get_h());
	
	// find a bounding rectangle for the context we need to render
	// todo: find a better way of doing this - this way doesn't work
	Rect src_rect(transform(tl));
	Point pos1, pos2;
	Real dist, along;
	Real min_dist(999999), max_dist(-999999), min_along(999999), max_along(-999999);
	
#define UPDATE_DIST \
if (dist < min_dist) min_dist = dist; \
if (dist > max_dist) max_dist = dist; \
if (along < min_along) min_along = along; \
if (along > max_along) max_along = along
	
	// look along the top and bottom edges
	pos1[0] = pos2[0] = tl[0]; pos1[1] = tl[1]; pos2[1] = br[1];
	for (x = 0; x < w; x++, pos1[0] += pw, pos2[0] += pw)
	{
		src_rect.expand(transform(pos1, &dist, &along)); UPDATE_DIST;
		src_rect.expand(transform(pos2, &dist, &along)); UPDATE_DIST;
	}
	
	// look along the left and right edges
	pos1[0] = tl[0]; pos2[0] = br[0]; pos1[1] = pos2[1] = tl[1];
	for (y = 0; y < h; y++, pos1[1] += ph, pos2[1] += ph)
	{
		src_rect.expand(transform(pos1, &dist, &along)); UPDATE_DIST;
		src_rect.expand(transform(pos2, &dist, &along)); UPDATE_DIST;
	}
	
	// look along the diagonals
	const int max_wh(std::max(w,h));
	const Real inc_x((br[0]-tl[0])/max_wh),inc_y((br[1]-tl[1])/max_wh);
	pos1[0] = pos2[0] = tl[0]; pos1[1] = tl[1]; pos2[1] = br[1];
	for (x = 0; x < max_wh; x++, pos1[0] += inc_x, pos2[0] = pos1[0], pos1[1]+=inc_y, pos2[1]-=inc_y)
	{
		src_rect.expand(transform(pos1, &dist, &along)); UPDATE_DIST;
		src_rect.expand(transform(pos2, &dist, &along)); UPDATE_DIST;
	}
	
#if 0
	// look at each blinepoint
	std::vector<synfig::BLinePoint>::const_iterator iter;
	for (iter=bline.begin(); iter!=bline.end(); iter++)
		src_rect.expand(transform(iter->get_vertex()+origin, &dist, &along)); UPDATE_DIST;
#endif
	
	Point src_tl(src_rect.get_min());
	Point src_br(src_rect.get_max());
	
	Vector ab((end_point - start_point).norm());
	Angle::tan ab_angle(ab[1], ab[0]);
	
	Real used_length = max_along - min_along;
	Real render_width = max_dist - min_dist;
	
	int src_w = (abs(used_length*Angle::cos(ab_angle).get()) +
				 abs(render_width*Angle::sin(ab_angle).get())) / abs(pw);
	int src_h = (abs(used_length*Angle::sin(ab_angle).get()) +
				 abs(render_width*Angle::cos(ab_angle).get())) / abs(ph);
	
	Real src_pw((src_br[0] - src_tl[0]) / src_w);
	Real src_ph((src_br[1] - src_tl[1]) / src_h);
	
	if (src_pw > abs(pw))
	{
		src_w = int((src_br[0] - src_tl[0]) / abs(pw));
		src_pw = (src_br[0] - src_tl[0]) / src_w;
	}
	
	if (src_ph > abs(ph))
	{
		src_h = int((src_br[1] - src_tl[1]) / abs(ph));
		src_ph = (src_br[1] - src_tl[1]) / src_h;
	}
	
#define MAXPIX 10000
	if (src_w > MAXPIX) src_w = MAXPIX;
	if (src_h > MAXPIX) src_h = MAXPIX;
	
	// this is an attempt to remove artifacts around tile edges - the
	// cubic interpolation uses at most 2 pixels either side of the
	// target pixel, so add an extra 2 pixels around the tile on all
	// sides
	src_tl -= (Point(src_pw,src_ph)*2);
	src_br += (Point(src_pw,src_ph)*2);
	src_w += 4;
	src_h += 4;
	src_pw = (src_br[0] - src_tl[0]) / src_w;
	src_ph = (src_br[1] - src_tl[1]) / src_h;
	
	// set up a renddesc for the context to render
	RendDesc src_desc(renddesc);
	//src_desc.clear_flags();
	src_desc.set_tl(src_tl);
	src_desc.set_br(src_br);
	src_desc.set_wh(src_w, src_h);
	
	
	// New expanded renddesc values
	const double wpw=src_desc.get_pw();
	const double wph=src_desc.get_ph();
	const double wtlx=src_desc.get_tl()[0];
	const double wtly=src_desc.get_tl()[1];

	// render the context onto a new surface
	
	cairo_surface_t* csource, *cresult;
	csource=cairo_surface_create_similar(cairo_get_target(cr),CAIRO_CONTENT_COLOR_ALPHA, src_w, src_h);
	cresult=cairo_surface_create_similar(cairo_get_target(cr),CAIRO_CONTENT_COLOR_ALPHA, w, h);
	cairo_t *subcr=cairo_create(csource);
	cairo_scale(subcr, 1/wpw, 1/wph);
	cairo_translate(subcr, -wtlx, -wtly);

	if(!context.accelerated_cairorender(subcr,quality,src_desc,&stageone))
		return false;
	// don't needed anymore
	cairo_destroy(subcr);
	//access to pixels
	CairoSurface source(csource);
	source.map_cairo_image();
	
	CairoSurface result(cresult);
	result.map_cairo_image();
	float u,v;
	Point pos, tmp;
		
	if(quality<=4)				// CUBIC
		for(y=0,pos[1]=tl[1];y<h;y++,pos[1]+=ph)
		{
			for(x=0,pos[0]=tl[0];x<w;x++,pos[0]+=pw)
			{
				tmp=transform(pos);
				u=(tmp[0]-src_tl[0])/src_pw;
				v=(tmp[1]-src_tl[1])/src_ph;
				if(u<0 || v<0 || u>=src_w || v>=src_h || isnan(u) || isnan(v))
					result[y][x]=CairoColor(context.get_color(tmp)).premult_alpha();
				else
					result[y][x]=source.cubic_sample_cooked(u,v);
			}
			if((y&31)==0 && cb && !stagetwo.amount_complete(y,h)) return false;
		}
	else if (quality<=6)		// INTERPOLATION_LINEAR
		for(y=0,pos[1]=tl[1];y<h;y++,pos[1]+=ph)
		{
			for(x=0,pos[0]=tl[0];x<w;x++,pos[0]+=pw)
			{
				tmp=transform(pos);
				u=(tmp[0]-src_tl[0])/src_pw;
				v=(tmp[1]-src_tl[1])/src_ph;
				if(u<0 || v<0 || u>=src_w || v>=src_h || isnan(u) || isnan(v))
					result[y][x]=CairoColor(context.get_color(tmp)).premult_alpha();
				else
					result[y][x]=source.linear_sample_cooked(u,v);
			}
			if((y&31)==0 && cb && !stagetwo.amount_complete(y,h)) return false;
		}
	else						// NEAREST_NEIGHBOR
		for(y=0,pos[1]=tl[1];y<h;y++,pos[1]+=ph)
		{
			for(x=0,pos[0]=tl[0];x<w;x++,pos[0]+=pw)
			{
				tmp=transform(pos);
				u=(tmp[0]-src_tl[0])/src_pw;
				v=(tmp[1]-src_tl[1])/src_ph;
				if(u<0 || v<0 || u>=src_w || v>=src_h || isnan(u) || isnan(v))
					result[y][x]=CairoColor(context.get_color(tmp)).premult_alpha();
				else
					result[y][x]=source[floor_to_int(v)][floor_to_int(u)];
			}
			if((y&31)==0 && cb && !stagetwo.amount_complete(y,h)) return false;
		}
	
	result.unmap_cairo_image();
	source.unmap_cairo_image();
	
	cairo_surface_destroy(csource);
	// Now paint it on the context
	cairo_save(cr);
	
	cairo_translate(cr, tl[0], tl[1]);
	cairo_scale(cr, pw, ph);
	cairo_set_source_surface(cr, cresult, 0, 0);
	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
	cairo_paint(cr);
	
	cairo_restore(cr);
	
	cairo_surface_destroy(cresult);
	
	// Mark our progress as finished
	if(cb && !cb->amount_complete(10000,10000))
		return false;
	
	return true;
}
Exemplo n.º 4
0
void OpenSGNavGrab::initScene()
{
   vprDEBUG_OutputGuard(vprDBG_ALL, vprDBG_CRITICAL_LVL,
                        "OpenSGNavGrab::initScene() called.\n",
                        "OpenSGNavGrab::initScene() exiting.\n");

   // Set up the node highlighting state.
   initHighlight();

   mModelRoot = OSG::Node::create();
   mModelGroup = OSG::Group::create();

#if OSG_MAJOR_VERSION < 2
   CPEdit(mModelRoot, OSG::Node::CoreFieldMask);
#endif

   mModelRoot->setCore(mModelGroup);

   // Load the model to use.
   if ( mFilesToLoad.empty() )
   {
      vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
         << "[OpenSGNavGrab::initScene()] No model specified; creating box."
         << std::endl << vprDEBUG_FLUSH;

      // Box geometry: 2.5x2.5x2.5 (units are in feet)
      // Center point: (0,0,0)
      OSG::NodeRefPtr geom_node(OSG::makeBox(2.5f, 2.5f, 2.5f, 1, 1, 1));

      // Move it so that it would butt up against a wall five feet in front
      // of the user and another wall five feet to the left of the user.
      // If the application units were meters, this placement would be very
      // different.
      OSG::Matrix init_geom_pos;
      init_geom_pos.setTransform(OSG::Vec3f(-3.75f, 1.25f, -3.75f));

      mObjects.push_back(makeGrabbable(geom_node, init_geom_pos));
   }
   else
   {
      OSG::Vec3f distance_vec;
      OSG::Pnt3f::RealReturnType max_dist(0.0f);

      std::vector<OSG::NodeRefPtr> nodes;

      // Load all the models that the user told us to load.
      typedef std::vector<std::string>::iterator iter_type;
      for ( iter_type i = mFilesToLoad.begin(); i != mFilesToLoad.end(); ++i )
      {
         vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
            << "[OpenSGNavGrab::initScene()] Loading '" << *i << "' ..."
            << std::endl << vprDEBUG_FLUSH;
         const OSG::Char8* file = (*i).c_str();
         OSG::NodeRefPtr geom_node(
#if OSG_MAJOR_VERSION < 2
            OSG::SceneFileHandler::the().read(file)
#else
            OSG::SceneFileHandler::the()->read(file)
#endif
         );

         nodes.push_back(geom_node);

         // Needed to get the volume set up after creating the geometry.
         geom_node->updateVolume();
         OSG::DynamicVolume volume = geom_node->getVolume();
         OSG::Pnt3f min, max;
         volume.getBounds(min, max);

         // Calculate the distance between min and max.  The largest distance
         // will be used for spacing out the objects.
         OSG::Pnt3f::RealReturnType dist(max.dist(min));

         // Keep track of the maximum-sized bounding volume.
         if ( dist > max_dist )
         {
            max_dist     = dist;
            distance_vec = max - min;
         }
      }

      std::cout << "distance_vec: " << distance_vec << std::endl;

      // If we have loaded any models, we will position them along the X-axis.
      // The extents of the line of models is based on the bounding volume of
      // the largest model and the number of models.  The line of models is
      // centered on the origin.  Hence, half the models will be have a
      // negative X translation value, and half will have a positive X
      // translation value.
      if ( ! nodes.empty() )
      {
         const std::vector<OSG::NodeRefPtr>::size_type num_objs(nodes.size());
         const OSG::Real32 interval_dist(distance_vec[0]);

         // Set the left extreme of the line of models.  The full extent of
         // the model range is interval_dist * num_objs.  To center things
         // on the origin, we divide that value by 2.  Since x_offset will
         // be used for the new center point of the model (see below), we
         // shift the starting point (interval_dist / 2) units so that some
         // model will end up centered on the origin.
         OSG::Real32 x_offset =
            -(interval_dist * OSG::Real32(num_objs) - interval_dist) / 2.0f;

         typedef std::vector<OSG::NodeRefPtr>::iterator iter_type;
         for ( iter_type i = nodes.begin();
               i != nodes.end();
               ++i, x_offset += interval_dist )
         {

            // Get the center point of the current node and change its X
            // component to be the current x_offset value.
            const OSG::DynamicVolume& volume = (*i)->getVolume();
            OSG::Pnt3f center;
            volume.getCenter(center);
            center[0] = x_offset;

            // The transformation matrix xform_mat will be the "home" position
            // for the model.
            OSG::Matrix xform_mat;
            xform_mat.setTranslate(center);
            mObjects.push_back(makeGrabbable(*i, xform_mat));
         }
      }
   }

   // --- Light setup --- //
   // - Add directional light for scene
   // - Create a beacon for it and connect to that beacon
   mLightNode   = OSG::Node::create();
   mLightBeacon = OSG::Node::create();
   OSG::DirectionalLightPtr light_core = OSG::DirectionalLight::create();
   OSG::TransformPtr light_beacon_core = OSG::Transform::create();

   // Set up light beacon
   OSG::Matrix light_pos;
   light_pos.setTransform(OSG::Vec3f(2.0f, 5.0f, 4.0f));

#if OSG_MAJOR_VERSION < 2
   CPEdit(light_beacon_core, OSG::Transform::MatrixFieldMask);
   CPEdit(mLightBeacon, OSG::Node::CoreFieldMask);
   CPEdit(mLightNode, OSG::Node::CoreFieldMask | OSG::Node::ChildrenFieldMask);
   CPEditAll(light_core);
#endif

   light_beacon_core->setMatrix(light_pos);

   mLightBeacon->setCore(light_beacon_core);

   // Set up light node
   mLightNode->setCore(light_core);
   mLightNode->addChild(mLightBeacon);

   light_core->setAmbient(0.9, 0.8, 0.8, 1);
   light_core->setDiffuse(0.6, 0.6, 0.6, 1);
   light_core->setSpecular(1, 1, 1, 1);
   light_core->setDirection(0, 0, 1);
   light_core->setBeacon(mLightNode);

   // --- Set up scene -- //
   // add the loaded scene to the light node, so that it is lit by the light
   mLightNode->addChild(mModelRoot);

   // create the root part of the scene
   mSceneRoot = OSG::Node::create();
   mSceneTransform = OSG::Transform::create();

#if OSG_MAJOR_VERSION < 2
   CPEdit(mSceneRoot, OSG::Node::CoreFieldMask | OSG::Node::ChildrenFieldMask);
#endif

   // Set up the root node
   mSceneRoot->setCore(mSceneTransform);
   mSceneRoot->addChild(mLightNode);
}