Esempio n. 1
0
void App::slotHelpAbout()
{
    AboutBox ab(this);
    ab.exec();
}
Esempio n. 2
0
ftype pointLineDist(const Point& p, const Point& a, const Point& b) {
  Vec ab(a, b), ap(a, p);
  return abs(ab.cross(ap)) / sqrt(ab.norm_sq());
}
Esempio n. 3
0
int main() {for (long long a,b,c,d,r;~scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&r);puts((ab(c-a)+ab(d-b) >r ? "alive" : "die"))) ;}
void I (int j) {
    int m,g,e;
    if( d == 288) {
        ad();
        ad();
        m= U ();
        ad();
        I (j);
        if( d == 312) {
            ad();
            g=B(0);
            A(m);
            I (j);
            A(g);
        }
        else {
            A(m);
        }
    }
    else if( d == 352|d == 504) {
        e=d;
        ad();
        ad();
        if( e == 352) {
            g=q;
            m= U ();
        }
        else {
            if( d!= 59)w ();
            ad();
            g=q;
            m= 0;
            if( d!= 59)m= U ();
            ad();
            if( d!= 41) {
                e=B(0);
                w ();
                B(g-q-5);
                A(e);
                g=e +4;
            }
        }
        ad();
        I(&m);
        B(g-q-5);
        A(m);
    }
    else if( d == 123) {
        ad();
        ab(1);
        while( d!= 125)I (j);
        ad();
    }
    else {
        if( d == 448) {
            ad();
            if( d!= 59)w ();
            K=B(K);
        }
        else if( d == 400) {
            ad();
            *(int*) j=B(*(int*) j);
        }
        else if( d!= 59)w ();
        ad();
    }
}
Esempio n. 5
0
void ImageSysData::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c)
{
	GuiLock __;
	x += w.GetOffset().x;
	y += w.GetOffset().y;
	Size sz = img.GetSize();
	int  len = sz.cx * sz.cy;
	Rect sr = src & sz;
	Size ssz = sr.Size();
	if(sr.IsEmpty())
		return;
	int kind = img.GetKind();
	if(kind == IMAGE_EMPTY)
		return;
	if(kind == IMAGE_OPAQUE && !IsNull(c)) {
		w.DrawRect(x, y, sz.cx, sz.cy, c);
		return;
	}
	if(kind == IMAGE_OPAQUE && paintcount == 0 && sr == Rect(sz)) {
		SetSurface(w, x, y, sz.cx, sz.cy, ~img);
		paintcount++;
		return;
	}
	if(IsNull(c)) {
		if(!picture) {
			bool opaque = kind == IMAGE_OPAQUE;
			Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, opaque ? 24 : 32);
			picture = XRenderCreatePicture(
				Xdisplay, pixmap,
			    XRenderFindStandardFormat(Xdisplay, opaque ? PictStandardRGB24
			                                               : PictStandardARGB32),
			    0, 0
			);
			XImage ximg;
			sInitXImage(ximg, sz);
			ximg.bitmap_pad = 32;
			ximg.bytes_per_line = 4 * sz.cx;
			ximg.bits_per_pixel = 32;
			ximg.blue_mask = 0x00ff0000;
			ximg.green_mask = 0x0000ff00;
			ximg.red_mask = 0x000000ff;
			ximg.bitmap_unit = 32;
			ximg.data = (char *)~img;
			ximg.depth = opaque ? 24 : 32;
			XInitImage(&ximg);
			GC gc = XCreateGC(Xdisplay, pixmap, 0, 0);
			XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, sz.cx, sz.cy);
			XFreeGC(Xdisplay, gc);
			XFreePixmap(Xdisplay, pixmap);
			SysImageRealized(img);
		}
		XRenderComposite(Xdisplay, PictOpOver,
		                 picture, 0, XftDrawPicture(w.GetXftDraw()),
		                 sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy);
	}
	else {
		if(!picture8) {
			Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, 8);
			picture8 = XRenderCreatePicture(Xdisplay, pixmap,
			                                XRenderFindStandardFormat(Xdisplay, PictStandardA8),
			                                0, 0);
			Buffer<byte> ab(len);
			byte *t = ab;
			const RGBA *s = ~img;
			const RGBA *e = s + len;
			while(s < e)
				*t++ = (s++)->a;
			XImage ximg;
			sInitXImage(ximg, sz);
			ximg.data             = (char *)~ab;
			ximg.bitmap_unit      = 8;
			ximg.bitmap_pad       = 8;
			ximg.depth            = 8;
			ximg.bytes_per_line   = sz.cx;
			ximg.bits_per_pixel   = 8;
			XInitImage(&ximg);
			GC gc = XCreateGC(Xdisplay, pixmap, 0, 0);
			XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, sz.cx, sz.cy);
			XFreeGC(Xdisplay, gc);
			XFreePixmap(Xdisplay, pixmap);
		}
		XRenderComposite(Xdisplay, PictOpOver,
		                 sGetSolidFill(c), picture8, XftDrawPicture(w.GetXftDraw()),
		                 sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy);
	}
}
Esempio n. 6
0
bool Edge3D::intercept(const Point3D &p1, const Point3D &p2) const
{
	double min, max, pmin, pmax;

	//if the bounding boxes of the two edges do not intercept, then
	//	the two edges do not intercept

	Point3D *tp1 = (Point3D *)this->getP1();
	Point3D *tp2 = (Point3D *)this->getP2();

	if (tp1->getX() > tp2->getX())
	{
		min = tp2->getX();
		max = tp1->getX();
	}
	else
	{
		min = tp1->getX();
		max = tp2->getX();
	}

	if (p1.getX() > p2.getX())
	{
		pmin = p2.getX();
		pmax = p1.getX();
	}
	else
	{
		pmin = p1.getX();
		pmax = p2.getX();
	}

	if ((min > pmax) || (max < pmin))
	{
		return false;
	}

	if (tp1->getY() > tp2->getY())
	{
		min = tp2->getY();
		max = tp1->getY();
	}
	else
	{
		min = tp1->getY();
		max = tp2->getY();
	}

	if (p1.getY() > p2.getY())
	{
		pmin = p2.getY();
		pmax = p1.getY();
	}
	else
	{
		pmin = p1.getY();
		pmax = p2.getY();
	}

	if ((min > pmax) || (max < pmin))
	{
		return false;
	}

	Vector3D ab(this->vector());
	Vector3D ac(*tp1, p1);
	Vector3D ad(*tp1, p2);

    Vector3D cd(p1, p2);
	Vector3D ca(p1, *tp1);
	Vector3D cb(p1, *tp2);

    return ( (ab.cross(ac).getX() * ab.cross(ad).getX() +
            ab.cross(ac).getY() * ab.cross(ad).getY() +
            ab.cross(ac).getZ() * ab.cross(ad).getZ() < 0.0)
            &&
            (cd.cross(ca).getX() * cd.cross(cb).getX() +
            cd.cross(ca).getY() * cd.cross(cb).getY() +
            cd.cross(ca).getZ() * cd.cross(cb).getZ() < 0.0) );
}
void HalfedgeMesh::build(const vector<vector<Index> >& polygons,
                         const vector<Vector3D>& vertexPositions)
// This method initializes the halfedge data structure from a raw list of
// polygons, where each input polygon is specified as a list of vertex indices.
// The input must describe a manifold, oriented surface, where the orientation
// of a polygon is determined by the order of vertices in the list. Polygons
// must have at least three vertices.  Note that there are no special conditions
// on the vertex indices, i.e., they do not have to start at 0 or 1, nor does
// the collection of indices have to be contiguous.  Overall, this initializer
// is designed to be robust but perhaps not incredibly fast (though of course
// this does not affect the performance of the resulting data structure).  One
// could also implement faster initializers that handle important special cases
// (e.g., all triangles, or data that is known to be manifold). Since there are
// no strong conditions on the indices of polygons, we assume that the list of
// vertex positions is given in lexicographic order (i.e., that the lowest index
// appearing in any polygon corresponds to the first entry of the list of
// positions and so on).
{
  // define some types, to improve readability
  typedef vector<Index> IndexList;
  typedef IndexList::const_iterator IndexListCIter;
  typedef vector<IndexList> PolygonList;
  typedef PolygonList::const_iterator PolygonListCIter;
  typedef pair<Index, Index> IndexPair;  // ordered pair of vertex indices,
                                         // corresponding to an edge of an
                                         // oriented polygon

  // Clear any existing elements.
  halfedges.clear();
  vertices.clear();
  edges.clear();
  faces.clear();
  boundaries.clear();

  // Since the vertices in our halfedge mesh are stored in a linked list,
  // we will temporarily need to keep track of the correspondence between
  // indices of vertices in our input and pointers to vertices in the new
  // mesh (which otherwise can't be accessed by index).  Note that since
  // we're using a general-purpose map (rather than, say, a vector), we can
  // be a bit more flexible about the indexing scheme: input vertex indices
  // aren't required to be 0-based or 1-based; in fact, the set of indices
  // doesn't even have to be contiguous.  Taking advantage of this fact makes
  // our conversion a bit more robust to different types of input, including
  // data that comes from a subset of a full mesh.

  // maps a vertex index to the corresponding vertex
  map<Index, VertexIter> indexToVertex;

  // Also store the vertex degree, i.e., the number of polygons that use each
  // vertex; this information will be used to check that the mesh is manifold.
  map<VertexIter, Size> vertexDegree;

  // First, we do some basic sanity checks on the input.
  for (PolygonListCIter p = polygons.begin(); p != polygons.end(); p++) {
    if (p->size() < 3) {
      // Refuse to build the mesh if any of the polygons have fewer than three
      // vertices.(Note that if we omit this check the code will still
      // constructsomething fairlymeaningful for 1- and 2-point polygons, but
      // enforcing this stricterrequirementon the input will help simplify code
      // further downstream, since it canbe certainit doesn't have to check for
      // these rather degenerate cases.)
      cerr << "Error converting polygons to halfedge mesh: each polygon must "
              "have at least three vertices." << endl;
      exit(1);
    }

    // We want to count the number of distinct vertex indices in this
    // polygon, to make sure it's the same as the number of vertices
    // in the polygon---if they disagree, then the polygon is not valid
    // (or at least, for simplicity we don't handle polygons of this type!).
    set<Index> polygonIndices;

    // loop over polygon vertices
    for (IndexListCIter i = p->begin(); i != p->end(); i++) {
      polygonIndices.insert(*i);

      // allocate one vertex for each new index we encounter
      if (indexToVertex.find(*i) == indexToVertex.end()) {
        VertexIter v = newVertex();
        v->halfedge() =
            halfedges.end();  // this vertex doesn't yet point to any halfedge
        indexToVertex[*i] = v;
        vertexDegree[v] = 1;  // we've now seen this vertex only once
      } else {
        // keep track of the number of times we've seen this vertex
        vertexDegree[indexToVertex[*i]]++;
      }

    }  // end loop over polygon vertices

    // check that all vertices of the current polygon are distinct
    Size degree = p->size();  // number of vertices in this polygon
    if (polygonIndices.size() < degree) {
      cerr << "Error converting polygons to halfedge mesh: one of the input "
              "polygons does not have distinct vertices!" << endl;
      cerr << "(vertex indices:";
      for (IndexListCIter i = p->begin(); i != p->end(); i++) {
        cerr << " " << *i;
      }
      cerr << ")" << endl;
      exit(1);
    }  // end check that polygon vertices are distinct

  }  // end basic sanity checks on input

  // The number of vertices in the mesh is the
  // number of unique indices seen in the input.
  Size nVertices = indexToVertex.size();

  // The number of faces is just the number of polygons in the input.
  Size nFaces = polygons.size();
  faces.resize(nFaces);  // allocate storage for faces in our new mesh

  // We will store a map from ordered pairs of vertex indices to
  // the corresponding halfedge object in our new (halfedge) mesh;
  // this map gets constructed during the next loop over polygons.
  map<IndexPair, HalfedgeIter> pairToHalfedge;

  // Next, we actually build the halfedge connectivity by again looping over
  // polygons
  PolygonListCIter p;
  FaceIter f;
  for (p = polygons.begin(), f = faces.begin(); p != polygons.end(); p++, f++) {
    vector<HalfedgeIter> faceHalfedges;  // cyclically ordered list of the half
                                         // edges of this face
    Size degree = p->size();             // number of vertices in this polygon

    // loop over the halfedges of this face (equivalently, the ordered pairs of
    // consecutive vertices)
    for (Index i = 0; i < degree; i++) {
      Index a = (*p)[i];                 // current index
      Index b = (*p)[(i + 1) % degree];  // next index, in cyclic order
      IndexPair ab(a, b);
      HalfedgeIter hab;

      // check if this halfedge already exists; if so, we have a problem!
      if (pairToHalfedge.find(ab) != pairToHalfedge.end()) {
        cerr << "Error converting polygons to halfedge mesh: found multiple "
                "oriented edges with indices (" << a << ", " << b << ")."
             << endl;
        cerr << "This means that either (i) more than two faces contain this "
                "edge (hence the surface is nonmanifold), or" << endl;
        cerr << "(ii) there are exactly two faces containing this edge, but "
                "they have the same orientation (hence the surface is" << endl;
        cerr << "not consistently oriented." << endl;
        exit(1);
      } else  // otherwise, the halfedge hasn't been allocated yet
      {
        // so, we point this vertex pair to a new halfedge
        hab = newHalfedge();
        pairToHalfedge[ab] = hab;

        // link the new halfedge to its face
        hab->face() = f;
        hab->face()->halfedge() = hab;

        // also link it to its starting vertex
        hab->vertex() = indexToVertex[a];
        hab->vertex()->halfedge() = hab;

        // keep a list of halfedges in this face, so that we can later
        // link them together in a loop (via their "next" pointers)
        faceHalfedges.push_back(hab);
      }

      // Also, check if the twin of this halfedge has already been constructed
      // (during construction of a different face).  If so, link the twins
      // together and allocate their shared halfedge.  By the end of this pass
      // over polygons, the only halfedges that will not have a twin will hence
      // be those that sit along the domain boundary.
      IndexPair ba(b, a);
      map<IndexPair, HalfedgeIter>::iterator iba = pairToHalfedge.find(ba);
      if (iba != pairToHalfedge.end()) {
        HalfedgeIter hba = iba->second;

        // link the twins
        hab->twin() = hba;
        hba->twin() = hab;

        // allocate and link their edge
        EdgeIter e = newEdge();
        hab->edge() = e;
        hba->edge() = e;
        e->halfedge() = hab;
      } else { // If we didn't find a twin...
        // ...mark this halfedge as being twinless by pointing
        // it to the end of the list of halfedges. If it remains
        // twinless by the end of the current loop over polygons,
        // it will be linked to a boundary face in the next pass.
        hab->twin() = halfedges.end();
      }

    }  // end loop over the current polygon's halfedges

    // Now that all the halfedges of this face have been allocated,
    // we can link them together via their "next" pointers.
    for (Index i = 0; i < degree; i++) {
      Index j =
          (i + 1) % degree;  // index of the next halfedge, in cyclic order
      faceHalfedges[i]->next() = faceHalfedges[j];
    }

  }  // done building basic halfedge connectivity

  // For each vertex on the boundary, advance its halfedge pointer to one that
  // is also on the boundary.
  for (VertexIter v = verticesBegin(); v != verticesEnd(); v++) {
    // loop over halfedges around vertex
    HalfedgeIter h = v->halfedge();
    do {
      if (h->twin() == halfedges.end()) {
        v->halfedge() = h;
        break;
      }

      h = h->twin()->next();
    } while (h != v->halfedge());  // end loop over halfedges around vertex

  }  // done advancing halfedge pointers for boundary vertices

  // Next we construct new faces for each boundary component.
  for (HalfedgeIter h = halfedgesBegin(); h != halfedgesEnd();
       h++)  // loop over all halfedges
  {
    // Any halfedge that does not yet have a twin is on the boundary of the
    // domain. If we follow the boundary around long enough we will of course
    // eventually make a closed loop; we can represent this boundary loop by a
    // new face. To make clear the distinction between faces and boundary loops,
    // the boundary face will (i) have a flag indicating that it is a boundary
    // loop, and (ii) be stored in a list of boundaries, rather than the usual
    // list of faces.  The reason we need the both the flag *and* the separate
    // list is that faces are often accessed in two fundamentally different
    // ways: either by (i) local traversal of the neighborhood of some mesh
    // element using the halfedge structure, or (ii) global traversal of all
    // faces (or boundary loops).
    if (h->twin() == halfedges.end()) {
      FaceIter b = newBoundary();
      vector<HalfedgeIter> boundaryHalfedges;  // keep a list of halfedges along
                                               // the boundary, so we can link
                                               // them together

      // We now need to walk around the boundary, creating new
      // halfedges and edges along the boundary loop as we go.
      HalfedgeIter i = h;
      do {
        // create a twin, which becomes a halfedge of the boundary loop
        HalfedgeIter t = newHalfedge();
        boundaryHalfedges.push_back(
            t);  // keep a list of all boundary halfedges, in cyclic order
        i->twin() = t;
        t->twin() = i;
        t->face() = b;
        t->vertex() = i->next()->vertex();

        // create the shared edge
        EdgeIter e = newEdge();
        e->halfedge() = i;
        i->edge() = e;
        t->edge() = e;

        // Advance i to the next halfedge along the current boundary loop
        // by walking around its target vertex and stopping as soon as we
        // find a halfedge that does not yet have a twin defined.
        i = i->next();
        while (i != h &&  // we're done if we end up back at the beginning of
                          // the loop
               i->twin() != halfedges.end())  // otherwise, we're looking for
                                              // the next twinless halfedge
                                              // along the loop
        {
          i = i->twin();
          i = i->next();
        }
      } while (i != h);

      // The only pointers that still need to be set are the "next" pointers of
      // the twins; these we can set from the list of boundary halfedges, but we
      // must use the opposite order from the order in the list, since the
      // orientation of the boundary loop is opposite the orientation of the
      // halfedges "inside" the domain boundary.
      Size degree = boundaryHalfedges.size();
      for (Index p = 0; p < degree; p++) {
        Index q = (p - 1 + degree) % degree;
        boundaryHalfedges[p]->next() = boundaryHalfedges[q];
      }

    }  // end construction of one of the boundary loops

    // Note that even though we are looping over all halfedges, we will still
    // construct the appropriate number of boundary loops (and not, say, one
    // loop per boundary halfedge).  The reason is that as we continue to
    // iterate through halfedges, we check whether their twin has been assigned,
    // and since new twins may have been assigned earlier in this loop, we will
    // end up skipping many subsequent halfedges.

  }  // done adding "virtual" faces corresponding to boundary loops

  // To make later traversal of the mesh easier, we will now advance the
  // halfedge
  // associated with each vertex such that it refers to the *first* non-boundary
  // halfedge, rather than the last one.
  for (VertexIter v = verticesBegin(); v != verticesEnd(); v++) {
    v->halfedge() = v->halfedge()->twin()->next();
  }

  // Finally, we check that all vertices are manifold.
  for (VertexIter v = vertices.begin(); v != vertices.end(); v++) {
    // First check that this vertex is not a "floating" vertex;
    // if it is then we do not have a valid 2-manifold surface.
    if (v->halfedge() == halfedges.end()) {
      cerr << "Error converting polygons to halfedge mesh: some vertices are "
              "not referenced by any polygon." << endl;
      exit(1);
    }

    // Next, check that the number of halfedges emanating from this vertex in
    // our half edge data structure equals the number of polygons containing
    // this vertex, which we counted during our first pass over the mesh.  If
    // not, then our vertex is not a "fan" of polygons, but instead has some
    // other (nonmanifold) structure.
    Size count = 0;
    HalfedgeIter h = v->halfedge();
    do {
      if (!h->face()->isBoundary()) {
        count++;
      }
      h = h->twin()->next();
    } while (h != v->halfedge());

    if (count != vertexDegree[v]) {
      cerr << "Error converting polygons to halfedge mesh: at least one of the "
              "vertices is nonmanifold." << endl;
      exit(1);
    }
  }  // end loop over vertices

  // Now that we have the connectivity, we copy the list of vertex
  // positions into member variables of the individual vertices.
  if (vertexPositions.size() != vertices.size()) {
    cerr << "Error converting polygons to halfedge mesh: number of vertex "
            "positions is different from the number of distinct vertices!"
         << endl;
    cerr << "(number of positions in input: " << vertexPositions.size() << ")"
         << endl;
    cerr << "(  number of vertices in mesh: " << vertices.size() << ")" << endl;
    exit(1);
  }
  // Since an STL map internally sorts its keys, we can iterate over the map
  // from vertex indices to vertex iterators to visit our (input) vertices in
  // lexicographic order
  int i = 0;
  for (map<Index, VertexIter>::const_iterator e = indexToVertex.begin();
       e != indexToVertex.end(); e++) {
    // grab a pointer to the vertex associated with the current key (i.e., the
    // current index)
    VertexIter v = e->second;

    // set the att of this vertex to the corresponding
    // position in the input
    v->position = vertexPositions[i];
    i++;
  }

  // compute initial normals
  for (VertexIter v = verticesBegin(); v != verticesEnd(); v++) {
    v->computeNormal();
  }

}  // end HalfedgeMesh::build()
Esempio n. 8
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;
}
Esempio n. 9
0
int main()
{
    Mercator::Terrain terrain;
    
    terrain.setBasePoint(0, 0, 2.8);
    terrain.setBasePoint(1, 0, 7.1);
    terrain.setBasePoint(0, 1, 0.2);
    terrain.setBasePoint(1, 1, 14.7);

    Mercator::Segment * segment = terrain.getSegment(0, 0);

    if (segment == 0) {
        std::cerr << "Segment not created by addition of required basepoints"
                  << std::endl << std::flush;
        return 1;
    }

    segment->populate();
    
    //test box definitely outside terrain
    WFMath::AxisBox<3> highab(WFMath::Point<3> (10.0, 10.0, segment->getMax() + 3.0), 
                          WFMath::Point<3> (20.0, 20.0, segment->getMax() + 6.1));

    if (Mercator::Intersect(terrain, highab)) {
        std::cerr << "axisbox intersects with terrain even though it should be above it"
            << std::endl;
        return 1;
    }

    //test box definitely inside terrain
    WFMath::AxisBox<3> lowab(WFMath::Point<3> (10.0, 10.0, segment->getMin() - 6.1), 
                          WFMath::Point<3> (20.0, 20.0, segment->getMax() - 3.0));

    if (!Mercator::Intersect(terrain, lowab)) {
        std::cerr << "axisbox does not intersect with terrain even though it should be below it"
            << std::endl;
        return 1;
    }


    //test axis box moved from above terrain to below it. 
    bool inter=false;
    float dz = highab.highCorner()[2] - highab.lowCorner()[2] - 0.1;
    while (highab.highCorner()[2] > segment->getMin()) {
        highab.shift(WFMath::Vector<3>(0.0, 0.0, -dz));
        if (Mercator::Intersect(terrain, highab)) {
            inter=true;
            break;
        }
    }
    
    if (!inter) {
        std::cerr << "axisbox passed through terrain with no intersection"
            << std::endl;
        return 1;
    }
     

    //test axisbox that spans two segments
    terrain.setBasePoint(0, 2, 4.8);
    terrain.setBasePoint(1, 2, 3.7);

    Mercator::Segment *segment2 = terrain.getSegment(0, 1);
    segment2->populate();

    float segmax=std::max(segment->getMax(), segment2->getMax());
    float segmin=std::min(segment->getMin(), segment2->getMin());
    
    WFMath::AxisBox<3> ab(WFMath::Point<3> (50.0, 10.0, segmax + 3.0), 
                          WFMath::Point<3> (70.0, 20.0, segmax + 6.1));

    if (Mercator::Intersect(terrain, ab)) {
        std::cerr << "axisbox2 intersects with terrain even though it should be above it"
            << std::endl;
        return 1;
    }

    WFMath::AxisBox<3> ab2(WFMath::Point<3> (50.0, 10.0, segmin - 6.1), 
                          WFMath::Point<3> (70.0, 20.0, segmin + 3.0));

    if (!Mercator::Intersect(terrain, ab2)) {
        std::cerr << "axisbox2 does not intersect with terrain even though it should be below it"
            << std::endl;
        return 1;
    }


    WFMath::Point<3> intPoint;
    WFMath::Vector<3> intNorm;
    float par;
    //test vertical ray
    if (Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(0.0,0.0,50.0), intPoint, intNorm, par)) {
        std::cerr << "vertical ray intersected when it shouldnt" << std::endl;
        return 1;
    }
    
    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(0.0,0.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "vertical ray didnt intersect when it should" << std::endl;
        return 1;
    }

    //test each quadrant
    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(10.0,10.0,-100.0), intPoint, intNorm, par)) {
        std::cerr << "quad1 ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(10.0,-15.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "quad2 ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(-10.0,-10.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "quad3 ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(-10.0,10.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "quad4 ray didnt intersect when it should" << std::endl;
        return 1;
    }
    
    //test dx==0 and dy==0
    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(0.0,10.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "y+ ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(0.0,-10.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "y- ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(-10.0,0.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "x- ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(10.0,0.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "x+ ray didnt intersect when it should" << std::endl;
        return 1;
    }
    
    //test a longer ray
    if (!Mercator::Intersect(terrain, WFMath::Point<3>(-10.08, -20.37, segmax + 3), 
                               WFMath::Vector<3>(100.0,183.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "long ray didnt intersect when it should" << std::endl;
        return 1;
    }
 
    //check the height value
    float h;
    WFMath::Vector<3> n;
    terrain.getHeightAndNormal(intPoint[0], intPoint[1], h, n);
    n.normalize();

    if (n != intNorm) {
        std::cerr << "calculated normal is different from getHeightAndNormal" << std::endl;
        std::cerr << intPoint << std::endl;
        std::cerr << intNorm << "!=" << n << std::endl;
       // return 1;
    }
    
    // We can't check for equality here is it just doesn't work with
    // floats. Look it up in any programming book if you don't believe me.
    //  - 20040721 <*****@*****.**>
    if (fabs(h - intPoint[2]) > 0.00001) {
        std::cerr << "calculated height is different from getHeightAndNormal" << std::endl;
        std::cerr << h << "!=" << intPoint[2] << std::endl;
        return 1;
    }
        
    return 0;
}
Esempio n. 10
0
void ContainerNode::setAttributeEventListener(const AtomicString& eventType, const QualifiedName& attributeName, const AtomicString& attributeValue)
{
    Attribute ab(attributeName,attributeValue);
    setAttributeEventListener(eventType, createAttributeEventListener(this, &ab));//CMP_ERROR , use v8 instead of jsc
}
Esempio n. 11
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;
}
Esempio n. 12
0
/**
 * メッシュ情報を読み込む
 *
 * @param mesh メッシュ情報
 */
void FbxFileLoader::load_mesh( FbxMesh* mesh )
{
	if ( ! mesh )
	{
		return;
	}

	if ( ! get_model()->get_mesh() )
	{
		get_model()->set_mesh( create_mesh() );
	}

	VertexIndexMap vertex_index_map;
	VertexList vertex_list;

	Mesh::PositionList position_list;
	Mesh::VertexWeightList vertex_weight_list;

	// load_mesh_vertex()
	for ( int n = 0; n < mesh->GetControlPointsCount(); n++ )
	{
		FbxVector4 v = mesh->GetControlPointAt( n );

		position_list.push_back(
			Mesh::Position(
				static_cast< float >( v[ 0 ] ),
				static_cast< float >( v[ 1 ] ),
				static_cast< float >( v[ 2 ] ) ) );
	}

	// load_mesh_vertex_weight()
	{
		int skin_count = mesh->GetDeformerCount( FbxDeformer::eSkin );

		if ( skin_count > 0 )
		{
			assert( skin_count == 1 );

			vertex_weight_list.resize( position_list.size() );

			FbxSkin* skin = FbxCast< FbxSkin >( mesh->GetDeformer( 0, FbxDeformer::eSkin ) );

			load_mesh_vertex_weight( skin, vertex_weight_list );
		}
	}

	FbxLayerElementSmoothing* smoothing = 0;

	// load_mesh_smoothing_info()
	{
		FbxLayer* layer = mesh->GetLayer( 0 );
		smoothing = layer->GetSmoothing();
	}

	if ( ! smoothing )
	{
		COMMON_THROW_EXCEPTION_MESSAGE( "this FBX format is not supported. ( no smoothing info )" );
	}

	// load_mesh_plygon()
	FbxLayerElementArrayTemplate< int >* material_indices;
	mesh->GetMaterialIndices( & material_indices );

	for ( int n = 0; n < mesh->GetPolygonCount(); n++ )
	{
		Mesh::VertexGroup* vertex_group = get_model()->get_mesh()->get_vertex_group_at( material_indices->GetAt( n ) );

		bool is_smooth = smoothing->GetDirectArray().GetAt( n ) != 0;
		FbxVector4 polygon_normal( 0.f, 0.f, 0.f );

		if ( ! is_smooth )
		{
			// ポリゴンの法線を計算する
			Mesh::Position p1( position_list.at( mesh->GetPolygonVertex( n, 0 ) ) );
			Mesh::Position p2( position_list.at( mesh->GetPolygonVertex( n, 1 ) ) );
			Mesh::Position p3( position_list.at( mesh->GetPolygonVertex( n, 2 ) ) );

			FbxVector4 a = FbxVector4( p1.x(), p1.y(), p1.z() );
			FbxVector4 b = FbxVector4( p2.x(), p2.y(), p2.z() );
			FbxVector4 c = FbxVector4( p3.x(), p3.y(), p3.z() );

			FbxVector4 ab( b - a );
			FbxVector4 bc( c - b );

			polygon_normal = ab.CrossProduct( bc );
			polygon_normal.Normalize();
		}

		for ( int m = 0; m < mesh->GetPolygonSize( n ); m++ )
		{
			int position_index = mesh->GetPolygonVertex( n, m );

			Mesh::Vertex v;
			v.Position = Mesh::Position( position_list.at( position_index ) );

			FbxVector2 uv_vector;
			bool unmapped;
			
			if ( mesh->GetPolygonVertexUV( n, m, "UVMap", uv_vector, unmapped) )
			{
				v.TexCoord = Mesh::TexCoord(
					static_cast< float >( uv_vector[ 0 ] ),
					1.f - static_cast< float >( uv_vector[ 1 ] ) );
			}

			if ( is_smooth )
			{
				FbxVector4 normal_vector;

				// 頂点の法線
				if ( mesh->GetPolygonVertexNormal( n, m, normal_vector ) )
				{
					v.Normal = Mesh::Normal(
						static_cast< float >( normal_vector[ 0 ] ),
						static_cast< float >( normal_vector[ 1 ] ),
						static_cast< float >( normal_vector[ 2 ] ) );
				}
			}
			else
			{
				// ポリゴンの法線
				v.Normal = Mesh::Normal(
					static_cast< float >( polygon_normal[ 0 ] ),
					static_cast< float >( polygon_normal[ 1 ] ),
					static_cast< float >( polygon_normal[ 2 ] ) );
			}
			
			// 頂点の一覧に追加
			{
				VertexIndexMap::iterator i = vertex_index_map.find( v );

				if ( i != vertex_index_map.end() )
				{
					vertex_group->add_index( i->second );
				}
				else
				{
					Mesh::Index vertex_index = static_cast< Mesh::Index >( get_model()->get_mesh()->get_vertex_count() );

					get_model()->get_mesh()->add_vertex( v );

					if ( ! vertex_weight_list.empty() )
					{
						get_model()->get_mesh()->add_vertex_weight( vertex_weight_list.at( position_index ) );
					}

					vertex_group->add_index( vertex_index );

					vertex_index_map[ v ] = vertex_index;
				}
			}
		}
	}
}
Esempio n. 13
0
int dist(point a,point b)
{
    return ab(a.x-b.x)+ab(a.y-b.y);
}
Esempio n. 14
0
bool in_triangle(point a, point* triangle) {
    vec ab(triangle[0], triangle[1]), bc(triangle[1], triangle[2]), ac(triangle[0], triangle[2]);
    return ((ab.cross(vec(triangle[0], a)) * vec(triangle[0], a).cross(ac) > 0 and 
        bc.cross(vec(triangle[1], a)) * vec(triangle[1], a).cross(vec(triangle[1], triangle[0])) > 0)) or a == triangle[0] or a == triangle[1] or a == triangle[2];
    return true; 
}
Esempio n. 15
0
	void DebugAABB2D()
	{
#pragma region TestShapes

		AABB2D ab(Vector2{ 10 , 10 }, Vector2{ 20 , 20 });
		AABB2D bb(Vector2{ 15 , 15 }, Vector2{ 25 , 25 });
		AABB2D cb(Vector2{ 25 , 25 }, Vector2{ 35 , 35 });

		Circle ac{ Vector2{10 , 15 }, 5 };
		Circle bc{ Vector2{0  , 0  }, 1 };
		Circle cc{ Vector2{25 , 25 }, 5 };

		Plane2D ap{ Vector2{15 ,15 } , Vector2{0 ,1 } };
		Plane2D bp{ Vector2{15 ,15 } , Vector2{1 ,0 } };
		Plane2D cp{ Vector2{0  ,0  } , Vector2{0 ,1 } };

		Ray2D ar{ Vector2{0,0 }, normal(Vector2{0.5,0.5}), 50 };
		Ray2D br{ Vector2{14.9f,1}, Vector2{0,1}, 50 };
		Ray2D cr{ Vector2{1,13}, Vector2{1,0}, 50 };

		ConvexHull2D chull;

		chull.size = 4;
		chull.verts[0] = Vector2{ 20,22 };
		chull.verts[1] = Vector2{ 23,18 };
		chull.verts[2] = Vector2{ 26,22 };
		chull.verts[3] = Vector2{ 23,28 };

#pragma endregion

		//AABB2D VS AABB2D
		assert( iTest(ab, bb));
		assert(!iTest(ab, cb));
		assert( iTest(bb, cb));

		//AABB2D VS CIRCLE
		assert( iTest(ab, ac));
		assert(!iTest(ab, bc));
		assert(!iTest(ab, cc));

		assert( iTest(bb, ac));
		assert(!iTest(bb, bc));
		assert( iTest(bb, cc));

		assert(!iTest(cb, ac));
		assert(!iTest(cb, bc));
		assert( iTest(cb, cc));

		//AABB2D VS PLANE
		assert( iTest(ab, ap));
		assert( iTest(ab, bp));
		assert(!iTest(ab, cp));

		assert( iTest(bb, ap));
		assert( iTest(bb, bp));
		assert(!iTest(bb, cp));

		assert(!iTest(cb, ap));
		assert(!iTest(cb, bp));
		assert(!iTest(cb, cp));

		//AABB2D VS RAY2D
		assert( iTest(ab, ar));
		assert( iTest(ab, br));
		assert( iTest(ab, cr));

		assert( iTest(bb, ar));
		assert(!iTest(bb, br));
		assert(!iTest(bb, cr));

		assert( iTest(cb, ar));
		assert(!iTest(cb, br));
		assert(!iTest(cb, cr));

		//AABB VS CONVEX2D
		assert(iTest_data(chull, ab).penDepth <= 0);
		assert(iTest_data(chull, bb).penDepth  > 0);
		assert(iTest_data(chull, cb).penDepth <= 0);
	}
osg::Geometry* ReaderWriterOBJ::convertElementListToGeometry(obj::Model& model, obj::Model::ElementList& elementList, ObjOptionsStruct& localOptions) const
{

    unsigned int numVertexIndices = 0;
    unsigned int numNormalIndices = 0;
    unsigned int numTexCoordIndices = 0;

    unsigned int numPointElements = 0;
    unsigned int numPolylineElements = 0;
    unsigned int numPolygonElements = 0;

    obj::Model::ElementList::iterator itr;

    if (localOptions.generateFacetNormals == true) {
        for(itr=elementList.begin();
                itr!=elementList.end();
                    ++itr)
        {
            obj::Element& element = *(*itr);
            if (element.dataType==obj::Element::POINTS || element.dataType==obj::Element::POLYLINE)
                continue;

            if (element.normalIndices.size() == 0) {
                // fill in the normals
                int a = element.vertexIndices[0];
                int b = element.vertexIndices[1];
                int c = element.vertexIndices[2];

                osg::Vec3f ab(model.vertices[b]);
                osg::Vec3f ac(model.vertices[c]);

                ab -= model.vertices[a];
                ac -= model.vertices[a];

                osg::Vec3f Norm( ab ^ ac );
                Norm.normalize();
                int normal_idx = model.normals.size();
                model.normals.push_back(Norm);

                for (unsigned i=0 ; i < element.vertexIndices.size() ; i++)
                    element.normalIndices.push_back(normal_idx);
            }
        }
    }



    for(itr=elementList.begin();
        itr!=elementList.end();
        ++itr)
    {
        obj::Element& element = *(*itr);

        numVertexIndices += element.vertexIndices.size();
        numNormalIndices += element.normalIndices.size();
        numTexCoordIndices += element.texCoordIndices.size();

        numPointElements += (element.dataType==obj::Element::POINTS) ? 1 : 0;
        numPolylineElements += (element.dataType==obj::Element::POLYLINE) ? 1 : 0;
        numPolygonElements += (element.dataType==obj::Element::POLYGON) ? 1 : 0;

    }

    if (numVertexIndices==0) return 0;

    if (numNormalIndices!=0 && numNormalIndices!=numVertexIndices)
    {
        OSG_NOTICE<<"Incorrect number of normals, ignore them"<<std::endl;
        numNormalIndices = 0;
    }

    if (numTexCoordIndices!=0 && numTexCoordIndices!=numVertexIndices)
    {
        OSG_NOTICE<<"Incorrect number of normals, ignore them"<<std::endl;
        numTexCoordIndices = 0;
    }

    osg::Vec3Array* vertices = numVertexIndices ? new osg::Vec3Array : 0;
    osg::Vec3Array* normals = numNormalIndices ? new osg::Vec3Array : 0;
    osg::Vec2Array* texcoords = numTexCoordIndices ? new osg::Vec2Array : 0;
    osg::Vec4Array* colors = (!model.colors.empty()) ? new osg::Vec4Array : 0;

    if (vertices) vertices->reserve(numVertexIndices);
    if (normals) normals->reserve(numNormalIndices);
    if (texcoords) texcoords->reserve(numTexCoordIndices);
    if (colors) colors->reserve(numVertexIndices);


    osg::Geometry* geometry = new osg::Geometry;
    if (vertices) geometry->setVertexArray(vertices);
    if (normals)
    {
        geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX);
    }

    if (texcoords)
    {
        geometry->setTexCoordArray(0,texcoords);
    }

    if (colors)
    {
        geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
    }

    if (numPointElements>0)
    {
        unsigned int startPos = vertices->size();
        unsigned int numPoints = 0;
        for(itr=elementList.begin();
            itr!=elementList.end();
            ++itr)
        {
            obj::Element& element = *(*itr);
            if (element.dataType==obj::Element::POINTS)
            {
                for(obj::Element::IndexList::iterator index_itr = element.vertexIndices.begin();
                    index_itr != element.vertexIndices.end();
                    ++index_itr)
                {
                    // if use color extension ( not standard but used by meshlab)
                    if (colors)
                    {
                        colors->push_back(model.colors[*index_itr]);
                    }
                    vertices->push_back(transformVertex(model.vertices[*index_itr],localOptions.rotate));
                    ++numPoints;
                }
                if (numNormalIndices)
                {
                    for(obj::Element::IndexList::iterator index_itr = element.normalIndices.begin();
                        index_itr != element.normalIndices.end();
                        ++index_itr)
                    {
                        normals->push_back(transformNormal(model.normals[*index_itr],localOptions.rotate));
                    }
                }
                if (numTexCoordIndices)
                {
                    for(obj::Element::IndexList::iterator index_itr = element.texCoordIndices.begin();
                        index_itr != element.texCoordIndices.end();
                        ++index_itr)
                    {
                        texcoords->push_back(model.texcoords[*index_itr]);
                    }
                }
            }
        }

        osg::DrawArrays* drawArrays = new osg::DrawArrays(GL_POINTS,startPos,numPoints);
        geometry->addPrimitiveSet(drawArrays);
    }

    if (numPolylineElements>0)
    {
        unsigned int startPos = vertices->size();
        osg::DrawArrayLengths* drawArrayLengths = new osg::DrawArrayLengths(GL_LINES,startPos);

        for(itr=elementList.begin();
            itr!=elementList.end();
            ++itr)
        {
            obj::Element& element = *(*itr);
            if (element.dataType==obj::Element::POLYLINE)
            {
                drawArrayLengths->push_back(element.vertexIndices.size());

                for(obj::Element::IndexList::iterator index_itr = element.vertexIndices.begin();
                    index_itr != element.vertexIndices.end();
                    ++index_itr)
                {
                    // if use color extension ( not standard but used by meshlab)
                    if (colors)
                    {
                        colors->push_back(model.colors[*index_itr]);
                    }

                    vertices->push_back(transformVertex(model.vertices[*index_itr],localOptions.rotate));
                }
                if (numNormalIndices)
                {
                    for(obj::Element::IndexList::iterator index_itr = element.normalIndices.begin();
                        index_itr != element.normalIndices.end();
                        ++index_itr)
                    {
                        normals->push_back(transformNormal(model.normals[*index_itr],localOptions.rotate));
                    }
                }
                if (numTexCoordIndices)
                {
                    for(obj::Element::IndexList::iterator index_itr = element.texCoordIndices.begin();
                        index_itr != element.texCoordIndices.end();
                        ++index_itr)
                    {
                        texcoords->push_back(model.texcoords[*index_itr]);
                    }
                }
            }
        }

        geometry->addPrimitiveSet(drawArrayLengths);

    }

    // #define USE_DRAWARRAYLENGTHS
    bool hasReversedFaces = false ;
    if (numPolygonElements>0)
    {
        unsigned int startPos = vertices->size();

        #ifdef USE_DRAWARRAYLENGTHS
            osg::DrawArrayLengths* drawArrayLengths = new osg::DrawArrayLengths(GL_POLYGON,startPos);
            geometry->addPrimitiveSet(drawArrayLengths);
        #endif

        for(itr=elementList.begin();
            itr!=elementList.end();
            ++itr)
        {
            obj::Element& element = *(*itr);
            if (element.dataType==obj::Element::POLYGON)
            {
                #ifdef USE_DRAWARRAYLENGTHS
                    drawArrayLengths->push_back(element.vertexIndices.size());
                #else
                    if (element.vertexIndices.size()>4)
                    {
                        osg::DrawArrays* drawArrays = new osg::DrawArrays(GL_POLYGON,startPos,element.vertexIndices.size());
                        startPos += element.vertexIndices.size();
                        geometry->addPrimitiveSet(drawArrays);
                    }
                    else
                    {
                        osg::DrawArrays* drawArrays = new osg::DrawArrays(GL_TRIANGLE_FAN,startPos,element.vertexIndices.size());
                        startPos += element.vertexIndices.size();
                        geometry->addPrimitiveSet(drawArrays);
                    }
                #endif


                if (model.needReverse(element) && !localOptions.noReverseFaces)
                {
                    hasReversedFaces = true;
                    // need to reverse so add to OSG arrays in same order as in OBJ, as OSG assume anticlockwise ordering.
                    for(obj::Element::IndexList::reverse_iterator index_itr = element.vertexIndices.rbegin();
                        index_itr != element.vertexIndices.rend();
                        ++index_itr)
                    {
                        // if use color extension ( not standard but used by meshlab)
                        if (colors)
                        {
                            colors->push_back(model.colors[*index_itr]);
                        }

                        vertices->push_back(transformVertex(model.vertices[*index_itr],localOptions.rotate));
                    }
                    if (numNormalIndices)
                    {
                        for(obj::Element::IndexList::reverse_iterator index_itr = element.normalIndices.rbegin();
                            index_itr != element.normalIndices.rend();
                            ++index_itr)
                        {
                            normals->push_back(transformNormal(model.normals[*index_itr],localOptions.rotate));
                        }
                    }


                    if (numTexCoordIndices)
                    {
                        for(obj::Element::IndexList::reverse_iterator index_itr = element.texCoordIndices.rbegin();
                            index_itr != element.texCoordIndices.rend();
                            ++index_itr)
                        {
                            texcoords->push_back(model.texcoords[*index_itr]);
                        }
                    }
                }
                else
                {
                    // no need to reverse so add to OSG arrays in same order as in OBJ.
                    for(obj::Element::IndexList::iterator index_itr = element.vertexIndices.begin();
                        index_itr != element.vertexIndices.end();
                        ++index_itr)
                    {
                        // if use color extension ( not standard but used by meshlab)
                        if (colors)
                        {
                            colors->push_back(model.colors[*index_itr]);
                        }

                        vertices->push_back(transformVertex(model.vertices[*index_itr],localOptions.rotate));
                    }
                    if (numNormalIndices)
                    {
                        for(obj::Element::IndexList::iterator index_itr = element.normalIndices.begin();
                            index_itr != element.normalIndices.end();
                            ++index_itr)
                        {
                            normals->push_back(transformNormal(model.normals[*index_itr],localOptions.rotate));
                        }
                    }
                    if (numTexCoordIndices)
                    {
                        for(obj::Element::IndexList::iterator index_itr = element.texCoordIndices.begin();
                            index_itr != element.texCoordIndices.end();
                            ++index_itr)
                        {
                            texcoords->push_back(model.texcoords[*index_itr]);
                        }
                    }
                }
            }
        }
    }

    if(hasReversedFaces)
    {
        OSG_WARN << "Warning: [ReaderWriterOBJ::convertElementListToGeometry] Some faces from geometry '" << geometry->getName() << "' were reversed by the plugin" << std::endl;
    }

    return geometry;
}