double vtIcoGlobe::AddSurfaceLineToMesh(vtGeomFactory *pMF, const DLine2 &line) { DPoint2 g1, g2; DPoint3 p1, p2; double scale = 1.0002; int length = 0; DMatrix3 rot3; pMF->PrimStart(); int i, j, size = line.GetSize(); for (i = 0; i < size-1; i++) { g1 = line.GetAt(i); g2 = line.GetAt(i+1); // for each pair of points, determine how many more points are needed // for a smooth arc geo_to_xyz(1.0, g1, p1); geo_to_xyz(1.0, g2, p2); double angle = acos(p1.Dot(p2)); int segments = (int) (angle * 2000); if (segments < 1) segments = 1; if (segments > 1) { // calculate the axis of rotation DPoint3 cross = p1.Cross(p2); cross.Normalize(); rot3.AxisAngle(cross, angle / segments); } // curved arc on great-circle path for (j = 0; j < segments; j++) { FPoint3 fp = p1 * 1.0002; pMF->AddVertex(fp); length++; if (j < segments-1) { rot3.Transform(p1, p2); p1 = p2; } } } // last vertex if (size > 1) { g2 = line.GetAt(size-1); geo_to_xyz(1.0, g2, p2); pMF->AddVertex(p2 * scale); length++; } pMF->PrimEnd(); return 0.0; }
void vtStructureArray::Offset(const DPoint2 &delta) { uint npoints = GetSize(); if (!npoints) return; uint i, j; DPoint2 temp; for (i = 0; i < npoints; i++) { vtStructure *str = GetAt(i); vtBuilding *bld = str->GetBuilding(); if (bld) bld->Offset(delta); vtFence *fen = str->GetFence(); if (fen) { DLine2 line = fen->GetFencePoints(); for (j = 0; j < line.GetSize(); j++) line.GetAt(j) += delta; } vtStructInstance *inst = str->GetInstance(); if (inst) inst->Offset(delta); } }
/** * Combine all vertices which are at the same location. By removing these * redundant vertices, the mesh will consume less space in memory and on disk. */ void vtTin::MergeSharedVerts(bool progress_callback(int)) { uint verts = NumVerts(); uint i, j; int bin; DRECT rect = m_EarthExtents; double width = rect.Width(); // make it slightly larger avoid edge condition rect.left -= 0.000001; width += 0.000002; m_bReplace = new int[verts]; m_vertbin = new Bin[BINS]; m_tribin = new Bin[BINS]; // sort the vertices into bins for (i = 0; i < verts; i++) { // flag all vertices initially not to remove m_bReplace[i] = -1; // find the correct bin, and add the index of this vertex to it bin = (int) (BINS * (m_vert[i].x - rect.left) / width); m_vertbin[bin].push_back(i); } uint trisize = m_tri.size(); for (i = 0; i < trisize; i++) { // find the correct bin, and add the index of this index to it bin = (int) (BINS * (m_vert[m_tri[i]].x - rect.left) / width); m_tribin[bin].push_back(i); } // compare within each bin, and between each adjacent bin, // looking for matching vertices to flag for removal for (bin = 0; bin < BINS; bin++) { if (progress_callback != NULL) progress_callback(bin * 100 / BINS); _CompareBins(bin, bin); if (bin < BINS-1) _CompareBins(bin, bin+1); } // now update each triangle index to point to the merge result for (bin = 0; bin < BINS; bin++) { if (progress_callback != NULL) progress_callback(bin * 100 / BINS); _UpdateIndicesInInBin(bin); } // now compact the vertex bins into a single array // make a copy to copy from DLine2 *vertcopy = new DLine2(m_vert); float *zcopy = new float[m_z.size()]; for (i = 0; i < m_z.size(); i++) zcopy[i] = m_z[i]; int inew = 0; // index into brand new array (actually re-using old) for (bin = 0; bin < BINS; bin++) { if (progress_callback != NULL) progress_callback(bin * 100 / BINS); uint binverts = m_vertbin[bin].size(); for (i = 0; i < binverts; i++) { int v_old = m_vertbin[bin].at(i); if (m_bReplace[v_old] != -1) continue; int v_new = inew; // copy old to new m_vert[v_new] = vertcopy->GetAt(v_old); m_z[v_new] = zcopy[v_old]; uint bintris = m_tribin[bin].size(); for (j = 0; j < bintris; j++) { int trindx = m_tribin[bin].at(j); if (m_tri[trindx] == v_old) m_tri[trindx] = v_new; } inew++; } } // our original array containers now hold the compacted result int newsize = inew; m_vert.SetSize(newsize); m_z.resize(newsize); // free up all the stuff we allocated delete [] m_bReplace; delete [] m_vertbin; delete [] m_tribin; delete vertcopy; delete [] zcopy; }