void Inkscape::ObjectSnapper::_snapPathsTangPerp(bool snap_tang, bool snap_perp, IntermSnapResults &isr, SnapCandidatePoint const &p, Geom::Curve const *curve, SPDesktop const *dt) const { // Here we will try to snap either tangentially or perpendicularly to a single path; for this we need to know where the origin is located of the line that is currently being rotated, // or we need to know the vector of the guide which is currently being translated std::vector<std::pair<Geom::Point, bool> > const origins_and_vectors = p.getOriginsAndVectors(); // Now we will iterate over all the origins and vectors and see which of these will get use a tangential or perpendicular snap for (std::vector<std::pair<Geom::Point, bool> >::const_iterator it_origin_or_vector = origins_and_vectors.begin(); it_origin_or_vector != origins_and_vectors.end(); ++it_origin_or_vector) { Geom::Point origin_or_vector_doc = dt->dt2doc((*it_origin_or_vector).first); // "first" contains a Geom::Point, denoting either a point or vector if ((*it_origin_or_vector).second) { // if "second" is true then "first" is a vector, otherwise it's a point // So we have a vector, which tells us what tangential or perpendicular direction we're looking for if (curve->degreesOfFreedom() <= 2) { // A LineSegment has order one, and therefore 2 DOF // When snapping to a point of a line segment that has a specific tangential or normal vector, then either all point // along that line will be snapped to or no points at all will be snapped to. This is not very useful, so let's skip // any line segments and lets only snap to higher order curves continue; } // The vector is being treated as a point (relative to the origin), and has been translated to document coordinates accordingly // We need however to make it a vector again, because also the origin has been transformed origin_or_vector_doc -= dt->dt2doc(Geom::Point(0,0)); } Geom::Point point_dt; Geom::Coord dist; std::vector<double> ts; if (snap_tang) { // Find all points that lead to a tangential snap if ((*it_origin_or_vector).second) { // if "second" is true then "first" is a vector, otherwise it's a point ts = find_tangents_by_vector(origin_or_vector_doc, curve->toSBasis()); } else { ts = find_tangents(origin_or_vector_doc, curve->toSBasis()); } for (std::vector<double>::const_iterator t = ts.begin(); t != ts.end(); ++t) { point_dt = dt->doc2dt(curve->pointAt(*t)); dist = Geom::distance(point_dt, p.getPoint()); isr.points.push_back(SnappedPoint(point_dt, p.getSourceType(), p.getSourceNum(), SNAPTARGET_PATH_TANGENTIAL, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, true)); } } if (snap_perp) { // Find all points that lead to a perpendicular snap if ((*it_origin_or_vector).second) { ts = find_normals_by_vector(origin_or_vector_doc, curve->toSBasis()); } else { ts = find_normals(origin_or_vector_doc, curve->toSBasis()); } for (std::vector<double>::const_iterator t = ts.begin(); t != ts.end(); ++t) { point_dt = dt->doc2dt(curve->pointAt(*t)); dist = Geom::distance(point_dt, p.getPoint()); isr.points.push_back(SnappedPoint(point_dt, p.getSourceType(), p.getSourceNum(), SNAPTARGET_PATH_PERPENDICULAR, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, true)); } } } }
int _tmain(int argc, _TCHAR* argv[]) { #ifdef WIN32 _fmode = _O_BINARY; #endif printf("This is QSplatMake version %s.\n", QSPLATMAKE_VERSION); // Parse command-line params //strncasecmp(char*s1,char*s2,size_t n):compare first n chars of s1 and s2 //ignore case and return 0 if equal else if s1>s2 return >0 else if s1<s2 return <0; if ((argc < 4) || !strncasecmp(argv[1], "-h", 2) || !strncasecmp(argv[1], "--h", 3)) usage(argv[0]); bool is_pointfile = false; int i = strncasecmp(argv[1], "point" , 5); if(!strncasecmp(argv[1], "point" , 5)) is_pointfile = true; const char *infilename = argv[2]; const char *outfilename = argv[3]; float threshold = 0; printf("argv2:%s\n",infilename); printf("argv3:%s\n",outfilename); if (argc >= 5 && !strncasecmp(argv[1], "-m", 2)) { threshold = atof(argv[2]); infilename = argv[3]; outfilename = argv[4]; } // Read the .ply file int numleaves, numfaces; face *faces; bool havecolor; QTree_Node *leaves; std::string comments; if (!read_ply(infilename, numleaves, leaves, numfaces, faces, havecolor, comments)) { fprintf(stderr, "Couldn't read input file %s\n", infilename); exit(1); } if (numleaves < 4) { fprintf(stderr, "Ummm... That's an awfully small mesh you've got there...\n"); exit(1); } if(!is_pointfile) if (numfaces < 4) { fprintf(stderr, "Ummm... I need a *mesh* as input. That means triangles 'n stuff...\n"); exit(1); } // Compute per-vertex normals if(!is_pointfile) { find_normals(numleaves, leaves, numfaces, faces); // Merge nodes merge_nodes(numleaves, leaves, numfaces, faces, havecolor, threshold); // Compute initial splat sizes find_splat_sizes(numleaves, leaves, numfaces, faces); } else { compute_splat_sizes(numleaves, leaves); } // Don't need face data any more delete [] faces; // Initialize the tree QTree qt(numleaves, leaves, havecolor); // Build the tree... qt.BuildTree(); // ... and write it out qt.Write(outfilename, comments); system("PAUSE"); return 0; }